From cff54b6b50238e7f5e06fbed4dabd541a458d472 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 30 Dec 2015 23:44:33 +0100 Subject: [PATCH] Unit tests for submission action --- src/server.c | 17 ++++++++-- test/Makefile.am | 10 ++++-- test/test-server-notify.c | 51 ++++++++++++++++++++++++++++ test/test-server-submit01.c | 66 +++++++++++++++++++++++++++++++++++++ test/test-server-submit02.c | 40 ++++++++++++++++++++++ test/test-server.inc | 48 +++++++++++++++++++++++++++ 6 files changed, 227 insertions(+), 5 deletions(-) create mode 100644 test/test-server-notify.c create mode 100644 test/test-server-submit01.c create mode 100644 test/test-server-submit02.c create mode 100644 test/test-server.inc diff --git a/src/server.c b/src/server.c index 9ff67bb..a1a4f94 100644 --- a/src/server.c +++ b/src/server.c @@ -109,7 +109,7 @@ static void cmusfm_server_process_data(int fd, scrobbler_session_t *sbs) { sock_data->duration); debug("location: %s", get_sock_data_location(sock_data)); -#if DEBUG +#if DEBUG && !defined(DEBUG_SKIP_HICCUP) /* simulate server "hiccup" (e.g. internet connection issue) */ debug("server hiccup test (5s)"); sleep(5); @@ -133,15 +133,26 @@ static void cmusfm_server_process_data(int fd, scrobbler_session_t *sbs) { scrobbler_fail_time = time(NULL); } - if (new_hash != prev_hash) { /* maybe it's time to submit :) */ + /* User is playing a new track or the status has changed for the previous + * one. In both cases we should check if the track should be submitted. */ + if (new_hash != prev_hash) { prev_hash = new_hash; action_submit: playtime += time(NULL) - unpaused; - if (started != 0 && (playtime * 100 / fulltime > 50 || playtime > 240)) { + + /* Track should be submitted if it is longer than 30 seconds and it has + * been played for at least half its duration (play time is greater than + * 15 seconds or 50% of the track duration respectively). Also the track + * should be submitted if the play time is greater than 4 minutes. */ + if (started != 0 && (playtime > fulltime - playtime || playtime > 240)) { + /* playing duration is OK so submit track */ set_trackinfo(&sb_tinf, (struct sock_data_tag*)saved_data); sb_tinf.timestamp = started; + if (sb_tinf.duration <= 30) + goto action_submit_skip; + if ((saved_is_radio && !config.submit_shoutcast) || (!saved_is_radio && !config.submit_localfile)) { /* skip submission if we don't want it */ diff --git a/test/Makefile.am b/test/Makefile.am index 2326b88..11485ac 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,7 +2,13 @@ # Copyright (c) 2015 Arkadiusz Bokowy TESTS = \ - test-cache + test-cache \ + test-server-notify \ + test-server-submit01 \ + test-server-submit02 check_PROGRAMS = \ - test-cache + test-cache \ + test-server-notify \ + test-server-submit01 \ + test-server-submit02 diff --git a/test/test-server-notify.c b/test/test-server-notify.c new file mode 100644 index 0000000..c585d32 --- /dev/null +++ b/test/test-server-notify.c @@ -0,0 +1,51 @@ +#include +#include "test-server.inc" + +int main(void) { + + char track_buffer[512]; + struct sock_data_tag *track = (struct sock_data_tag *)track_buffer; + + track->duration = 35; + track->alboff = 20; + track->titoff = 40; + track->locoff = 60; + strcpy(((char *)(track + 1)), "The Beatles"); + strcpy(((char *)(track + 1)) + 20, ""); + strcpy(((char *)(track + 1)) + 40, "Yellow Submarine"); + strcpy(((char *)(track + 1)) + 60, ""); + + /* data communication facility */ + int fd[2]; + assert(pipe(fd) != -1); + + config.nowplaying_localfile = 1; + config.nowplaying_shoutcast = 1; + + track->status = CMSTATUS_PLAYING; + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_update_now_playing_count == 1); + + config.nowplaying_localfile = 0; + + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_update_now_playing_count == 1); + assert(strcmp(scrobbler_update_now_playing_sbt.artist, "The Beatles") == 0); + assert(strcmp(scrobbler_update_now_playing_sbt.track, "Yellow Submarine") == 0); + +#if ENABLE_LIBNOTIFY + config.notification = 1; +#endif + + track->status |= CMSTATUS_SHOUTCASTMASK; + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_update_now_playing_count == 2); +#if ENABLE_LIBNOTIFY + assert(cmusfm_notify_show_count == 1); +#endif + + return EXIT_SUCCESS; +} diff --git a/test/test-server-submit01.c b/test/test-server-submit01.c new file mode 100644 index 0000000..af957ab --- /dev/null +++ b/test/test-server-submit01.c @@ -0,0 +1,66 @@ +#include + +#define DEBUG_SKIP_HICCUP +#include "test-server.inc" + +int main(void) { + + char track_buffer[512]; + struct sock_data_tag *track = (struct sock_data_tag *)track_buffer; + + track->alboff = 20; + track->titoff = 40; + track->locoff = 60; + strcpy(((char *)(track + 1)), "The Beatles"); + strcpy(((char *)(track + 1)) + 20, ""); + strcpy(((char *)(track + 1)) + 40, "Yellow Submarine"); + strcpy(((char *)(track + 1)) + 60, ""); + + /* data communication facility */ + int fd[2]; + assert(pipe(fd) != -1); + + config.submit_localfile = 1; + config.submit_shoutcast = 1; + + track->status = CMSTATUS_PLAYING; + track->duration = 35; + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + + /* track was played for more than half its duration */ + sleep(track->duration / 2 + 1); + + track->status = CMSTATUS_PLAYING; + track->duration = 35; + strcpy(((char *)(track + 1)) + 40, "For No One"); + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_scrobble_count == 1); + + /* track was played for less than half its duration */ + sleep(track->duration / 2 - 1); + + track->duration = 30; + strcpy(((char *)(track + 1)) + 40, "Doctor Robert"); + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_scrobble_count == 1); + + /* whole track was played but its duration isn't longer than 30 seconds */ + sleep(track->duration); + + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_scrobble_count == 1); + + /* short track was overplayed (due to seeking) */ + sleep(track->duration + 10); + + track->status = CMSTATUS_STOPPED; + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_scrobble_count == 1); + + return EXIT_SUCCESS; +} diff --git a/test/test-server-submit02.c b/test/test-server-submit02.c new file mode 100644 index 0000000..ca36434 --- /dev/null +++ b/test/test-server-submit02.c @@ -0,0 +1,40 @@ +#include + +#define DEBUG_SKIP_HICCUP +#include "test-server.inc" + +int main(void) { + + char track_buffer[512]; + struct sock_data_tag *track = (struct sock_data_tag *)track_buffer; + + track->alboff = 20; + track->titoff = 40; + track->locoff = 60; + strcpy(((char *)(track + 1)), "The Beatles"); + strcpy(((char *)(track + 1)) + 20, ""); + strcpy(((char *)(track + 1)) + 40, "Yellow Submarine"); + strcpy(((char *)(track + 1)) + 60, ""); + + /* data communication facility */ + int fd[2]; + assert(pipe(fd) != -1); + + config.submit_localfile = 1; + config.submit_shoutcast = 1; + + track->status = CMSTATUS_PLAYING; + track->duration = 4 * 60 * 5; + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + + /* track was played for more than 4 minutes but less than half its duration */ + sleep(4 * 60 + 1); + + track->status = CMSTATUS_STOPPED; + write(fd[1], track_buffer, sizeof(track_buffer)); + cmusfm_server_process_data(fd[0], NULL); + assert(scrobbler_scrobble_count == 1); + + return EXIT_SUCCESS; +} diff --git a/test/test-server.inc b/test/test-server.inc new file mode 100644 index 0000000..ba79edb --- /dev/null +++ b/test/test-server.inc @@ -0,0 +1,48 @@ +#include "../src/cmusfm.h" +#include "../src/server.c" +#include "../src/utils.c" + +/* global variables used in the server code */ +unsigned char SC_api_key[16] = { 0 }; +unsigned char SC_secret[16] = { 0 }; +struct cmusfm_config config = { 0 }; +const char *cmusfm_config_file = NULL; +const char *cmusfm_socket_file = NULL; + +/* mock subscription subsystem - with the invocation counter */ +scrobbler_trackinfo_t scrobbler_scrobble_sbt = { 0 }; +int scrobbler_scrobble_count = 0; +int scrobbler_scrobble(scrobbler_session_t *sbs, scrobbler_trackinfo_t *sbt) { + memcpy(&scrobbler_scrobble_sbt, sbt, sizeof(scrobbler_scrobble_sbt)); + scrobbler_scrobble_count++; + return 0; +} + +/* mock now-playing subsystem - with the invocation counter */ +scrobbler_trackinfo_t scrobbler_update_now_playing_sbt = { 0 }; +int scrobbler_update_now_playing_count = 0; +int scrobbler_update_now_playing(scrobbler_session_t *sbs, scrobbler_trackinfo_t *sbt) { + memcpy(&scrobbler_update_now_playing_sbt, sbt, sizeof(scrobbler_update_now_playing_sbt)); + scrobbler_update_now_playing_count++; + return 0; +} + +/* mock notification subsystem - with the invocation counter */ +scrobbler_trackinfo_t cmusfm_notify_show_sbt = { 0 }; +int cmusfm_notify_show_count = 0; +void cmusfm_notify_show(const scrobbler_trackinfo_t *sbt, const char *icon) { + memcpy(&cmusfm_notify_show_sbt, sbt, sizeof(cmusfm_notify_show_sbt)); + cmusfm_notify_show_count++; +} + +/* other (irrelevant) functions used by the server code */ +void cmusfm_cache_update(const scrobbler_trackinfo_t *sbt) {} +void cmusfm_cache_submit(scrobbler_session_t *sbs) {} +int cmusfm_config_read(const char *fname, struct cmusfm_config *conf) { return 0; } +int cmusfm_config_add_watch(int fd) { return 0; } +void cmusfm_notify_initialize() {} +void cmusfm_notify_free() {} +scrobbler_session_t *scrobbler_initialize(uint8_t api_key[16], uint8_t secret[16]) { return NULL; } +void scrobbler_free(scrobbler_session_t *sbs) {} +void scrobbler_set_session_key_str(scrobbler_session_t *sbs, const char *str) {} +int scrobbler_test_session_key(scrobbler_session_t *sbs) { return 0; }