output: add _get_plugin()
[libmpdclient.git] / test / main.c
blob0ef1509f88c91dffcfeb2d62f235d9d289eb7eb1
1 /* libmpdclient
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
7 are met:
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>
35 #include <mpd/song.h>
36 #include <mpd/entity.h>
37 #include <mpd/search.h>
38 #include <mpd/tag.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
44 #define BRIGHT 1
45 #define RED 31
46 #define GREEN 32
47 #define YELLOW 33
48 #define BG_BLACK 40
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);\
69 else\
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)); \
77 return -1; \
80 static int
81 test_new_connection(struct mpd_connection **conn)
83 *conn = mpd_connection_new(NULL, 0, 30000);
84 if (*conn == NULL) {
85 LOG_ERROR("%s", "Out of memory");
86 return -1;
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);
92 *conn = NULL;
93 return -1;
95 return 0;
98 static int
99 test_version(struct mpd_connection *conn)
101 int i, total = -1;
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 */
108 return total;
111 static void
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);
141 static void
142 print_tag(const struct mpd_song *song, enum mpd_tag_type type,
143 const char *label)
145 unsigned i = 0;
146 const char *value;
148 while ((value = mpd_song_get_tag(song, type, i++)) != NULL)
149 LOG_INFO("%s: %s", label, value);
152 static void
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));
172 static int
173 test_status(struct mpd_connection *conn)
175 struct mpd_status *status;
177 status = mpd_run_status(conn);
178 if (!status) {
179 LOG_ERROR("%s", mpd_connection_get_error_message(conn));
180 return -1;
183 print_status(status);
184 mpd_status_free(status);
186 mpd_response_finish(conn);
187 CHECK_CONNECTION(conn);
189 return 0;
192 static int
193 test_currentsong(struct mpd_connection *conn)
195 struct mpd_song *song;
197 song = mpd_run_current_song(conn);
198 if (song != NULL) {
199 print_song(song);
201 mpd_song_free(song);
204 mpd_response_finish(conn);
205 CHECK_CONNECTION(conn);
207 return 0;
211 static int
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);
226 if (!status) {
227 LOG_ERROR("%s", mpd_connection_get_error_message(conn));
228 return -1;
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);
240 if (entity) {
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);
245 return -1;
248 song = mpd_entity_get_song(entity);
250 print_song(song);
252 mpd_entity_free(entity);
255 mpd_response_finish(conn);
256 CHECK_CONNECTION(conn);
258 return 0;
261 static int
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");
277 break;
279 case MPD_ENTITY_TYPE_SONG:
280 song = mpd_entity_get_song(entity);
281 print_song (song);
282 break;
284 case MPD_ENTITY_TYPE_DIRECTORY:
285 dir = mpd_entity_get_directory(entity);
286 printf("directory: %s\n", mpd_directory_get_path(dir));
287 break;
289 case MPD_ENTITY_TYPE_PLAYLIST:
290 pl = mpd_entity_get_playlist(entity);
291 LOG_INFO("playlist: %s", mpd_playlist_get_path(pl));
292 break;
295 mpd_entity_free(entity);
298 mpd_response_finish(conn);
299 CHECK_CONNECTION(conn);
301 return 0;
304 static int
305 test_list_artists(struct mpd_connection *conn)
307 struct mpd_pair *pair;
308 int first = 1;
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) {
316 if (first) {
317 printf(" %s", pair->value);
318 first = 0;
319 } else {
320 printf(", %s", pair->value);
322 mpd_return_pair(conn, pair);
324 printf("\n");
326 mpd_response_finish(conn);
327 CHECK_CONNECTION(conn);
329 return 0;
332 static int
333 test_close_connection(struct mpd_connection *conn)
335 mpd_connection_free(conn);
336 return 0;
340 main(int argc, char ** argv)
342 struct mpd_connection *conn = NULL;
343 const char *lsinfo_path = "/";
345 if (argc==2)
346 lsinfo_path = argv[1];
348 START_TEST("Test connection to MPD server", test_new_connection, &conn);
349 if (!conn)
350 return -1;
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);
360 return 0;