From 926091cb640e8ccc2f0ee12acba116c01c442805 Mon Sep 17 00:00:00 2001 From: emeric Date: Fri, 10 Oct 2014 23:31:41 +0200 Subject: [PATCH] Renamed test to 'remote-client', added a missing test --- test/Makefile.am | 22 +- test/RemoteClientServer.cpp | 857 ------------------------------------ 2 files changed, 6 insertions(+), 873 deletions(-) delete mode 100644 test/RemoteClientServer.cpp diff --git a/test/Makefile.am b/test/Makefile.am index d1105468..cb2081d0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,22 +1,12 @@ TESTS = database-integrity sql-query database-user remote -check_PROGRAMS = database-integrity sql-query database-user remote +check_PROGRAMS = database-integrity sql-query database-user remote-client -remote_SOURCES = \ - $(srcdir)/RemoteClientServer.cpp \ - $(srcdir)/TestDatabase.cpp \ - $(top_srcdir)/src/logger/Logger.cpp \ - $(top_srcdir)/src/database/Artist.cpp \ - $(top_srcdir)/src/database/Genre.cpp \ - $(top_srcdir)/src/database/Release.cpp \ - $(top_srcdir)/src/database/Track.cpp \ - $(top_srcdir)/src/database/DatabaseHandler.cpp \ - $(top_srcdir)/src/database/MediaDirectory.cpp \ - $(top_srcdir)/src/database/SqlQuery.cpp \ - $(top_srcdir)/src/database/User.cpp \ - $(top_srcdir)/src/database/Video.cpp -nodist_remote_SOURCES = \ +remote_client_SOURCES = \ + $(srcdir)/RemoteClient.cpp \ + $(top_srcdir)/src/logger/Logger.cpp +nodist_remote_client_SOURCES = \ $(builddir)/auth.pb.cc \ $(builddir)/collection.pb.cc \ $(builddir)/common.pb.cc \ @@ -31,7 +21,7 @@ BUILT_SOURCES = \ $(builddir)/messages.pb.h -remote_CXXFLAGS=-std=c++11 -Wall -Wextra -DBOOST_LOG_DYN_LINK -I$(top_srcdir) -I$(top_srcdir)/src +remote_client_CXXFLAGS=-std=c++11 -Wall -Wextra -DBOOST_LOG_DYN_LINK -I$(top_srcdir) -I$(top_srcdir)/src %.pb.cc %.pb.h: $(top_srcdir)/src/remote/proto/%.proto $(PROTOC) --proto_path=$(top_srcdir)/src/remote/proto/ --cpp_out=$(builddir)/ $^ diff --git a/test/RemoteClientServer.cpp b/test/RemoteClientServer.cpp deleted file mode 100644 index 58ec4a75..00000000 --- a/test/RemoteClientServer.cpp +++ /dev/null @@ -1,857 +0,0 @@ -/* - * Copyright (C) 2013 Emeric Poupon - * - * This file is part of LMS. - * - * LMS is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LMS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LMS. If not, see . - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "remote/messages/Header.hpp" -#include "messages.pb.h" - -#include "TestDatabase.hpp" - -struct GenreInfo -{ - uint64_t id; - std::string name; -}; - -std::ostream& operator<<(std::ostream& os, const GenreInfo& info) -{ - os << "id = " << info.id << ", name = '" << info.name << "'"; - return os; -} - -struct ArtistInfo -{ - uint64_t id; - std::string name; -}; - -std::ostream& operator<<(std::ostream& os, const ArtistInfo& info) -{ - os << "id = " << info.id << ", name = '" << info.name << "'"; - return os; -} - -struct ReleaseInfo -{ - uint64_t id; - std::string name; -}; - -std::ostream& operator<<(std::ostream& os, const ReleaseInfo& info) -{ - os << "id = " << info.id << ", name = '" << info.name; - return os; -} - -struct TrackInfo -{ - uint64_t id; - - uint64_t release_id; - uint64_t artist_id; - std::vector genre_id; - - uint32_t disc_number; - uint32_t track_number; - - std::string name; - - boost::posix_time::time_duration duration; - - TrackInfo(): id(0), release_id(0), artist_id(0), disc_number(0), track_number(0) {} -}; - -std::ostream& operator<<(std::ostream& os, const TrackInfo& info) -{ - os << "id = " << info.id << ", name = '" << info.name << "', track_number = " << info.track_number << ", duration = " << info.duration; - return os; -} - -struct Cover -{ - std::string mimeType; - std::vector data; -}; - -// Ugly class for testing purposes - -class TestClient -{ - public: - TestClient(boost::asio::ip::tcp::endpoint endpoint) - : _context(boost::asio::ssl::context::sslv23), // be large on this - _socket(_ioService, _context) - { - boost::asio::ip::tcp::resolver resolver(_ioService); - - _socket.set_verify_mode(boost::asio::ssl::verify_peer); - _socket.set_verify_callback(boost::bind(&TestClient::verifyCertificate, this, _1, _2)); - - boost::asio::connect(_socket.lowest_layer(), resolver.resolve(endpoint)); - - _socket.handshake(boost::asio::ssl::stream_base::client); - } - - void getArtists(std::vector& artists, const std::vector& genreIds) - { - - const std::size_t requestedBatchSize = 128; - std::size_t offset = 0; - std::size_t res = 0; - - - while ((res = getArtists(artists, genreIds, offset, requestedBatchSize) ) > 0) - offset += res; - - } - - std::size_t getArtists(std::vector& artists, const std::vector& genreIds, std::size_t offset, std::size_t size) - { - std::size_t nbArtists = 0; - - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest ); - - request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetArtistList); - request.mutable_audio_collection_request()->mutable_get_artists()->mutable_batch_parameter()->set_size(size); - request.mutable_audio_collection_request()->mutable_get_artists()->mutable_batch_parameter()->set_offset(offset); - BOOST_FOREACH(uint64_t genreId, genreIds) - request.mutable_audio_collection_request()->mutable_get_artists()->add_genre_id(genreId); - - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.has_audio_collection_response()) - throw std::runtime_error("not an audio_collection_response!"); - - if (!response.audio_collection_response().has_artist_list()) - throw std::runtime_error("not an artist_list!"); - - for (int i = 0; i < response.audio_collection_response().artist_list().artists_size(); ++i) - { - if (!response.audio_collection_response().artist_list().artists(i).has_name()) - throw std::runtime_error("no artist name!"); - - ArtistInfo artist; - artist.id = response.audio_collection_response().artist_list().artists(i).id(); - artist.name = response.audio_collection_response().artist_list().artists(i).name(); - - artists.push_back( artist ); - nbArtists++; - } - - return nbArtists; - } - - void getGenres(std::vector& genres) - { - - const std::size_t requestedBatchSize = 8; - std::size_t offset = 0; - std::size_t res = 0; - - while ((res = getGenres(genres, offset, requestedBatchSize) ) > 0) - offset += res; - - } - - std::size_t getGenres(std::vector& genres, std::size_t offset, std::size_t size) - { - std::size_t nbAdded = 0; - - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest ); - - request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetGenreList); - request.mutable_audio_collection_request()->mutable_get_genres()->mutable_batch_parameter()->set_size(size); - request.mutable_audio_collection_request()->mutable_get_genres()->mutable_batch_parameter()->set_offset(offset); - - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.has_audio_collection_response()) - throw std::runtime_error("not an audio_collection_response!"); - - if (!response.audio_collection_response().has_genre_list()) - throw std::runtime_error("not an genre_list!"); - - for (int i = 0; i < response.audio_collection_response().genre_list().genres_size(); ++i) - { - if (!response.audio_collection_response().genre_list().genres(i).has_name()) - throw std::runtime_error("no genre name!"); - - GenreInfo genre; - genre.id = response.audio_collection_response().genre_list().genres(i).id(); - genre.name = response.audio_collection_response().genre_list().genres(i).name(); - - genres.push_back( genre ); - nbAdded++; - } - return nbAdded; - } - - void getReleases(std::vector& releases, const std::vector artistIds) - { - - const std::size_t requestedBatchSize = 256; - std::size_t offset = 0; - std::size_t res = 0; - - while ((res = getReleases(releases, artistIds, offset, requestedBatchSize) ) > 0) - offset += res; - - } - - std::size_t getReleases(std::vector& releases, const std::vector artistIds, std::size_t offset, std::size_t size) - { - std::size_t nbAdded = 0; - - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest ); - - request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetReleaseList); - request.mutable_audio_collection_request()->mutable_get_releases()->mutable_batch_parameter()->set_size(size); - request.mutable_audio_collection_request()->mutable_get_releases()->mutable_batch_parameter()->set_offset(offset); - BOOST_FOREACH(uint64_t artistId, artistIds) - request.mutable_audio_collection_request()->mutable_get_releases()->add_artist_id(artistId); - - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.audio_collection_response().has_type()) - throw std::runtime_error("Missing type!"); - -// if (!response.audio_collection_response().type() != Remote::ServerMessage::AudioCollectionResponse::TypeReleaseList) -// throw std::runtime_error("Bad type!"); - - if (!response.has_audio_collection_response()) - throw std::runtime_error("not an audio_collection_response!"); - - if (!response.audio_collection_response().has_release_list()) - throw std::runtime_error("not an release list!"); - - for (int i = 0; i < response.audio_collection_response().release_list().releases_size(); ++i) - { - if (!response.audio_collection_response().release_list().releases(i).has_name()) - throw std::runtime_error("no release name!"); - - ReleaseInfo release; - release.id = response.audio_collection_response().release_list().releases(i).id(); - release.name = response.audio_collection_response().release_list().releases(i).name(); - - releases.push_back( release ); - nbAdded++; - } - return nbAdded; - } - - void getTracks(std::vector& tracks, const std::vector artistIds, const std::vector releaseIds, const std::vector genreIds) - { - const std::size_t requestedBatchSize = 0; - std::size_t offset = 0; - std::size_t res = 0; - - while ((res = getTracks(tracks, artistIds, releaseIds, genreIds, offset, requestedBatchSize) ) > 0) - offset += res; - } - - std::size_t getTracks(std::vector& tracks, - const std::vector artistIds, - const std::vector releaseIds, - const std::vector genreIds, - std::size_t offset, - std::size_t size) - { - std::size_t nbAdded = 0; - - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage_Type_AudioCollectionRequest ); - - request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest_Type_TypeGetTrackList); - request.mutable_audio_collection_request()->mutable_get_tracks()->mutable_batch_parameter()->set_size(size); - request.mutable_audio_collection_request()->mutable_get_tracks()->mutable_batch_parameter()->set_offset(offset); - - BOOST_FOREACH(uint64_t artistId, artistIds) - request.mutable_audio_collection_request()->mutable_get_tracks()->add_artist_id(artistId); - BOOST_FOREACH(uint64_t releaseId, releaseIds) - request.mutable_audio_collection_request()->mutable_get_tracks()->add_release_id(releaseId); - BOOST_FOREACH(uint64_t genreId, genreIds) - request.mutable_audio_collection_request()->mutable_get_tracks()->add_genre_id(genreId); - - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.has_audio_collection_response()) - throw std::runtime_error("not an audio_collection_response!"); - - if (!response.audio_collection_response().has_track_list()) - throw std::runtime_error("not an track list!"); - - for (int i = 0; i < response.audio_collection_response().track_list().tracks_size(); ++i) - { - - TrackInfo track; - track.id = response.audio_collection_response().track_list().tracks(i).id(); - track.name = response.audio_collection_response().track_list().tracks(i).name(); - track.duration = boost::posix_time::seconds(response.audio_collection_response().track_list().tracks(i).duration_secs()); - if (response.audio_collection_response().track_list().tracks(i).has_track_number()) - track.track_number = response.audio_collection_response().track_list().tracks(i).track_number(); - - if (response.audio_collection_response().track_list().tracks(i).has_disc_number()) - track.disc_number = response.audio_collection_response().track_list().tracks(i).disc_number(); - - - tracks.push_back( track ); - nbAdded++; - } - - return nbAdded; - } - - - void getMediaAudio(uint64_t audioId, std::vector& data) - { - - // Prepare - uint32_t handle = mediaAudioPrepare( audioId ); - - // Get while available - mediaGet( handle, data ); - - // Terminate - mediaTerminate( handle ); - } - - void getCoverTrack(std::vector& coverArt, uint64_t trackId) - { - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage::AudioCollectionRequest ); - - request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetCoverArt); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_type( Remote::AudioCollectionRequest::GetCoverArt::TypeGetCoverArtTrack); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_track_id( trackId ); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 256 ); - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.has_audio_collection_response()) - throw std::runtime_error("not an audio_collection_response!"); - - for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i) - { - Cover cover; - cover.mimeType = response.audio_collection_response().cover_art(i).mime_type(); - cover.data.assign(response.audio_collection_response().cover_art(i).data().begin(), response.audio_collection_response().cover_art(i).data().end());; - - coverArt.push_back(cover); - } - } - - void getCoverRelease(std::vector& coverArt, uint64_t releaseId) - { - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage::AudioCollectionRequest ); - - request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetCoverArt); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_type( Remote::AudioCollectionRequest::GetCoverArt::TypeGetCoverArtRelease); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_release_id( releaseId ); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 256 ); - - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.has_audio_collection_response()) - throw std::runtime_error("not an audio_collection_response!"); - - for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i) - { - Cover cover; - cover.mimeType = response.audio_collection_response().cover_art(i).mime_type(); - cover.data.assign(response.audio_collection_response().cover_art(i).data().begin(), response.audio_collection_response().cover_art(i).data().end());; - - coverArt.push_back(cover); - } - - } - - std::string getRevision(void) - { - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage::AudioCollectionRequest ); - - request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetRevision); - - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.has_audio_collection_response()) - throw std::runtime_error("not an audio_collection_response!"); - - if (!response.audio_collection_response().has_revision()) - throw std::runtime_error("not a revision!"); - - return response.audio_collection_response().revision().rev(); - } - - bool login(const std::string& username, const std::string& password) - { - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage::AuthRequest ); - - request.mutable_auth_request()->set_type( Remote::AuthRequest::TypePassword); - request.mutable_auth_request()->mutable_password()->set_user_login( username ); - request.mutable_auth_request()->mutable_password()->set_user_password( password ); - - sendMsg(request); - - // Receive responses - Remote::ServerMessage response; - recvMsg(response); - - // Process message - if (!response.has_auth_response()) - throw std::runtime_error("not an auth response!"); - - if (!response.auth_response().has_password_result()) - throw std::runtime_error("not a password result!"); - - switch( response.auth_response().password_result().type()) - { - case Remote::AuthResponse::PasswordResult::TypePasswordValid: - return true; - case Remote::AuthResponse::PasswordResult::TypePasswordInvalid: - return false; - case Remote::AuthResponse::PasswordResult::TypeLoginThrottling: - if (response.auth_response().password_result().has_delay()) - std::cerr << "Has to wait for " << response.auth_response().password_result().delay() << " seconds" << std::endl; - - return false; - default: - throw std::runtime_error("bad password result type"); - } - } - - private: - - bool verifyCertificate(bool preverified, boost::asio::ssl::verify_context& ctx) - { - // In this example we will simply print the certificate's subject name. - std::array subject_name; - - X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); - X509_NAME_oneline(X509_get_subject_name(cert), subject_name.data(), subject_name.size()); - - std::cout << "Verifying '" << std::string(subject_name.data()) << "', preverified = " << std::boolalpha << preverified << std::endl; - - return true; // preverified; - } - - uint32_t mediaAudioPrepare(uint64_t audioId) - { - - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage_Type_MediaRequest); - - request.mutable_media_request()->set_type( Remote::MediaRequest_Type_TypeMediaPrepare); - request.mutable_media_request()->mutable_prepare()->set_type(Remote::MediaRequest_Prepare_Type_AudioRequest); - - // Set fields - request.mutable_media_request()->mutable_prepare()->mutable_audio()->set_track_id( audioId ); - request.mutable_media_request()->mutable_prepare()->mutable_audio()->set_codec_type( Remote::MediaRequest::Prepare::AudioCodecTypeOGA ); - request.mutable_media_request()->mutable_prepare()->mutable_audio()->set_bitrate( Remote::MediaRequest::Prepare::AudioBitrate_64_kbps ); - - std::cout << "Sending prepare request" << std::endl; - sendMsg(request); - - std::cout << "Waiting for response" << std::endl; - // Receive response - Remote::ServerMessage response; - recvMsg(response); - - std::cout << "Got a response" << std::endl; - - // Process message - if (!response.has_media_response()) - throw std::runtime_error("Preapre: not an media reponse!"); - - if (!response.media_response().has_prepare_result()) - throw std::runtime_error("Prepare: not an prepare result msg!"); - - if (!response.media_response().prepare_result().has_handle()) - throw std::runtime_error("Prepare: cannot get handle"); - - return response.media_response().prepare_result().handle(); - } - - void mediaGet(uint32_t handle, std::vector& data) - { - while (mediaGetPart(handle, data) > 0) - ; - } - - - std::size_t mediaGetPart(uint32_t handle, std::vector& data) - { - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage::MediaRequest); - - request.mutable_media_request()->set_type( Remote::MediaRequest::TypeMediaGetPart); - request.mutable_media_request()->mutable_get_part()->set_handle(handle); - request.mutable_media_request()->mutable_get_part()->set_requested_data_size(65536); - - std::cout << "Sending GetPart request" << std::endl; - sendMsg(request); - - std::cout << "Waiting for response" << std::endl; - // Receive response - Remote::ServerMessage response; - recvMsg(response); - - std::cout << "Got a response" << std::endl; - - if (!response.has_media_response()) - throw std::runtime_error("not an media response"); - - // Process message - if (response.media_response().type() != Remote::MediaResponse::TypePartResult) - throw std::runtime_error("GetPart: not a Part response!"); - - if (!response.media_response().has_part_result()) - throw std::runtime_error("GetPart: does not have a Part result!"); - - std::copy(response.media_response().part_result().data().begin(), response.media_response().part_result().data().end(), std::back_inserter(data)); - - return response.media_response().part_result().data().size(); - } - - void mediaTerminate( uint32_t handle ) - { - // Send request - Remote::ClientMessage request; - - request.set_type( Remote::ClientMessage::MediaRequest); - - request.mutable_media_request()->set_type( Remote::MediaRequest::TypeMediaTerminate); - request.mutable_media_request()->mutable_terminate()->set_handle(handle); - - sendMsg(request); - - // Receive response - Remote::ServerMessage response; - recvMsg(response); - - - // Process message - if (!response.has_media_response()) - throw std::runtime_error("Terminate: not an media response"); - - if (!response.media_response().has_terminate_result()) - throw std::runtime_error("Terminate: not an terminate msg!"); - - } - - - void sendMsg(const ::google::protobuf::Message& message) - { - std::ostream os(&_outputStreamBuf); - - // Serialize message - if (message.SerializeToOstream(&os)) - { - - if (_outputStreamBuf.size() > Remote::Header::max_data_size) - { - std::ostringstream oss; oss << "Message too big = " << _outputStreamBuf.size() << " bytes! (max is " << Remote::Header::max_data_size << ")" << std::endl; - throw std::runtime_error("Message to big!"); - } - - // Send message header - std::array headerBuffer; - - // Generate header content - { - Remote::Header header; - header.setDataSize(_outputStreamBuf.size()); - header.to_buffer(headerBuffer); - } - - boost::asio::write(_socket, boost::asio::buffer(headerBuffer)); - - // Send serialized message - std::size_t n = boost::asio::write(_socket, - _outputStreamBuf.data(), - boost::asio::transfer_exactly(_outputStreamBuf.size())); - assert(n == _outputStreamBuf.size()); - - _outputStreamBuf.consume(n); - - } - else - { - std::cerr << "Cannot serialize message!" << std::endl; - throw std::runtime_error("message.SerializeToString failed!"); - } - - } - - void recvMsg(::google::protobuf::Message& message) - { - std::istream is(&_inputStreamBuf); - - { - // reserve bytes in output sequence - boost::asio::streambuf::mutable_buffers_type bufs = _inputStreamBuf.prepare(Remote::Header::size); - - std::size_t n = boost::asio::read(_socket, - bufs, - boost::asio::transfer_exactly(Remote::Header::size)); - - assert(n == Remote::Header::size); - _inputStreamBuf.commit(n); - - } - - Remote::Header header; - if (!header.from_istream(is)) - throw std::runtime_error("Cannot read header from buffer!"); - - // Read in a stream buffer - { - // reserve bytes in output sequence - boost::asio::streambuf::mutable_buffers_type bufs = _inputStreamBuf.prepare(header.getDataSize()); - - std::size_t n = boost::asio::read(_socket, - bufs, - boost::asio::transfer_exactly(header.getDataSize())); - - assert(n == header.getDataSize()); - _inputStreamBuf.commit(n); - - if (!message.ParseFromIstream(&is)) - throw std::runtime_error("message.ParseFromIstream failed!"); - - } - } - - typedef boost::asio::ssl::stream ssl_socket; - - boost::asio::io_service _ioService; - boost::asio::ssl::context _context; - ssl_socket _socket; - - boost::asio::streambuf _inputStreamBuf; - boost::asio::streambuf _outputStreamBuf; - -}; - - -int main() -{ - try { - bool extendedTests = true; - bool writeCovers = false; - - std::cout << "Running test... extendedTests = " << std::boolalpha << extendedTests << std::endl; - - // Client - // connect to loopback - TestClient client( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4::loopback(), 5080)); - - // Use a dumb account in order to test the login - if (!client.login("admin", "admin")) - throw std::runtime_error("login failed!"); - - // **** REVISION *** - std::cout << "Getting revision..." << std::endl; - std::string rev = client.getRevision(); - std::cout << "Revision '" << rev << "'" << std::endl; - - // ****** Artists ********* - std::cout << "Getting artists..." << std::endl; - std::vector artists; - client.getArtists(artists, std::vector()); - - std::cout << "Got " << artists.size() << " artists!" << std::endl; - BOOST_FOREACH(const ArtistInfo& artist, artists) - std::cout << "Artist: '" << artist << "'" << std::endl; - - // ***** Genres ********* - std::cout << "Getting genres..." << std::endl; - std::vector genres; - client.getGenres(genres); - - std::cout << "Got " << genres.size() << " genres!" << std::endl; - BOOST_FOREACH(const GenreInfo& genre, genres) - std::cout << "Genre: '" << genre << "'" << std::endl; - - // **** Releases ****** - std::cout << "Getting releases..." << std::endl; - std::vector releases; - client.getReleases(releases, std::vector()); - BOOST_FOREACH(const ReleaseInfo& release, releases) - std::cout << "Release: '" << release << "'" << std::endl; - - // **** Tracks ****** - std::cout << "Getting tracks..." << std::endl; - std::vector tracks; - client.getTracks(tracks, std::vector(), std::vector(), std::vector()); - BOOST_FOREACH(const TrackInfo& track, tracks) - std::cout << "Track: '" << track << "'" << std::endl; - - // Caution: long test! - if (extendedTests) - { - - std::cout << "Getting artist for each genre..." << std::endl; - // Get the artists for each genre - BOOST_FOREACH(const GenreInfo& genre, genres) - { - std::cout << "Getting artists genre '" << genre.name << "'" << std::endl; - std::vector artists; - client.getArtists(artists, std::vector(1, genre.id)); - - BOOST_FOREACH(const ArtistInfo& artist, artists) - std::cout << "-> Artist: " << artist << std::endl; - } - - std::cout << "Getting tracks for each artist..." << std::endl; - // Get the tracks for each artist - BOOST_FOREACH(const ArtistInfo& artist, artists) - { - std::vector tracks; - client.getTracks(tracks, std::vector(1, artist.id), std::vector(), std::vector()); - - std::cout << "Artist '" << artist.name << "', nb tracks = " << tracks.size() << std::endl; - BOOST_FOREACH(const TrackInfo& track, tracks) - std::cout << "Artist '" << artist.name << "', track: '" << track << "'" << std::endl; - } - } - - // ***** Covers ******* - if (extendedTests) - { - BOOST_FOREACH(const ReleaseInfo& release, releases) - { - std::vector coverArts; - client.getCoverRelease(coverArts, release.id); - - if (writeCovers) - { - boost::filesystem::create_directory("cover"); - BOOST_FOREACH(const Cover coverArt, coverArts) - { - std::ostringstream oss; oss << "cover/" << release.id << "." << release.name << ".jpeg"; - std::ofstream out(oss.str().c_str()); - BOOST_FOREACH(unsigned char c, coverArt.data) - out.put(c); - } - } - - std::cout << "Release '" << release << "', spotted " << coverArts.size() << " covers!" << std::endl; - } - - BOOST_FOREACH(const TrackInfo& track, tracks) - { - std::vector coverArt; - client.getCoverTrack(coverArt, track.id); - - std::cout << "Track '" << track << "', spotted " << coverArt.size() << " covers!" << std::endl; - } - - } - - // ****** Transcode test ******** - const std::vector mediaIds = {14000, 14001}; - BOOST_FOREACH(uint64_t mediaId, mediaIds) - { - std::vector data; - client.getMediaAudio(mediaId, data); - std::cout << "Media size = " << data.size() << std::endl; - } - - std::cout << "End of tests!" << std::endl; - } - catch(std::exception& e) - { - std::cerr << "Caught exception " << e.what() << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Normal quit..." << std::endl; - return EXIT_SUCCESS; -} - -