1#
2# This file is part of Test-Corpus-Audio-MPD
3#
4# This software is copyright (c) 2009 by Jerome Quelin.
5#
6# This is free software; you can redistribute it and/or modify it under
7# the same terms as the Perl 5 programming language system itself.
8#
9use 5.008;
10use strict;
11use warnings;
12
13package Test::Corpus::Audio::MPD;
14{
15  $Test::Corpus::Audio::MPD::VERSION = '1.120990';
16}
17# ABSTRACT: automate launching of fake mdp for testing purposes
18
19use File::Copy                qw{ copy     };
20use File::ShareDir::PathClass qw{ dist_dir };
21use File::Temp                qw{ tempdir  };
22use Path::Class;
23use Readonly;
24
25use base qw{ Exporter };
26our @EXPORT = qw{
27    customize_test_mpd_configuration
28    playlist_dir
29    start_test_mpd stop_test_mpd
30};
31
32Readonly my $SHAREDIR    => dist_dir('Test-Corpus-Audio-MPD');
33Readonly my $TEMPLATE    => $SHAREDIR->file( 'mpd.conf.template' );
34Readonly my $TMPDIR      => dir( tempdir( CLEANUP=>1 ) );
35Readonly my $CONFIG      => $TMPDIR->file( 'mpd.conf' );
36Readonly my $PLAYLISTDIR => $TMPDIR->subdir( 'playlists' );
37
38
39{ # this will be run when module will be use-d
40
41    # check if mpd (the real music player daemon, not freebsd's
42    # multilink ppp daemon
43    my $output = qx{ mpd --version 2>&1 } or die "mpd not installed";
44    die "installed mpd is not music player daemon"
45        unless $output =~ /Music Player Daemon/;
46
47    my $restart = 0;
48    my $stopit  = 0;
49
50    $restart = _stop_user_mpd_if_needed();
51    customize_test_mpd_configuration();
52    $stopit  = start_test_mpd();
53
54    END {
55        stop_test_mpd() if $stopit;
56        return unless $restart;       # no need to restart
57        system 'mpd 2>/dev/null';     # restart user mpd
58        sleep 1;                      # wait 1 second to let mpd start.
59    }
60}
61
62
63# -- public subs
64
65
66sub customize_test_mpd_configuration {
67    my ($port) = @_;
68    $port ||= 6600;
69
70    # open template and config.
71    open my $in,  '<',  $TEMPLATE or die "can't open [$TEMPLATE]: $!";
72    open my $out, '>',  $CONFIG   or die "can't open [$CONFIG]: $!";
73
74    # replace string and fill in config file.
75    while ( defined( my $line = <$in> ) ) {
76        $line =~ s!PWD!$SHAREDIR!;
77        $line =~ s!TMP!$TMPDIR!;
78        $line =~ s!PORT!$port!;
79        print $out $line;
80    }
81
82    # clean up.
83    close $in;
84    close $out;
85
86    # copy the playlists. playlist need to be in a writable directory,
87    # since tests will create and remove some playlists.
88    $PLAYLISTDIR->mkpath;
89    copy( glob("$SHAREDIR/playlists/*"), $PLAYLISTDIR );
90}
91
92
93
94sub playlist_dir { $PLAYLISTDIR }
95
96
97
98sub start_test_mpd {
99    my $output = qx{ mpd $CONFIG 2>&1 };
100    my $rv = $? >>8;
101    die "could not start fake mpd: $output\n" if $rv;
102    sleep 1;   # wait 1 second to let mpd start.
103    return 1;
104}
105
106
107
108sub stop_test_mpd {
109    system "mpd --kill $CONFIG 2>/dev/null";
110    sleep 1;   # wait 1 second to free output device.
111    unlink "$TMPDIR/state", "$TMPDIR/music.db";
112}
113
114
115# -- private subs
116
117#
118# my $was_running = _stop_user_mpd_if_needed()
119#
120# This sub will check if mpd is currently running. If it is, force it to
121# a full stop (unless MPD_TEST_OVERRIDE is not set).
122#
123# In any case, it will return a boolean stating whether mpd was running
124# before forcing stop.
125#
126sub _stop_user_mpd_if_needed {
127    # check if mpd is running.
128    my $is_running = grep { /\s+mpd$/ } qx{ ps -e };
129
130    return 0 unless $is_running; # mpd does not run - nothing to do.
131
132    # check force stop.
133    die "mpd is running\n" unless $ENV{MPD_TEST_OVERRIDE};
134    system( 'mpd --kill 2>/dev/null') == 0 or die "can't stop user mpd: $?\n";
135    sleep 1;  # wait 1 second to free output device
136    return 1;
137}
138
139
1401;
141
142
143=pod
144
145=head1 NAME
146
147Test::Corpus::Audio::MPD - automate launching of fake mdp for testing purposes
148
149=head1 VERSION
150
151version 1.120990
152
153=head1 SYNOPSIS
154
155    use Test::Corpus::Audio::MPD; # die if error
156    [...]
157    stop_test_mpd();
158
159=head1 DESCRIPTION
160
161This module will try to launch a new mpd server for testing purposes.
162This mpd server will then be used during L<POE::Component::Client::MPD>
163or L<Audio::MPD> tests.
164
165In order to achieve this, the module will create a fake F<mpd.conf> file
166with the correct pathes (ie, where you untarred the module tarball). It
167will then check if some mpd server is already running, and stop it if
168the C<MPD_TEST_OVERRIDE> environment variable is true (die otherwise).
169Last it will run the test mpd with its newly created configuration file.
170
171Everything described above is done automatically when the module
172is C<use>-d.
173
174Once the tests are run, the mpd server will be shut down, and the
175original one will be relaunched (if there was one).
176
177Note that the test mpd will listen to C<localhost>, so you are on the
178safe side. Note also that the test suite comes with its own ogg files.
179Those files are 2 seconds tracks recording my voice saying ok, and are
180freely redistributable under the same license as the code itself.
181
182In case you want more control on the test mpd server, you can use the
183supplied public methods. This might be useful when trying to test
184connections with mpd server.
185
186=head1 METHODS
187
188=head2 customize_test_mpd_configuration( [$port] );
189
190Create a fake mpd configuration file, based on the file
191F<mpd.conf.template> located in F<share> subdir. The string PWD will be
192replaced by the real path (ie, where the tarball has been untarred),
193while TMP will be replaced by a new temp directory. The string PORT will
194be replaced by C<$port> if specified, 6600 otherwise (MPD's default).
195
196=head2 my $dir = playlist_dir();
197
198Return the temp dir where the test playlists will be stored.
199
200=head2 start_test_mpd();
201
202Start the fake mpd, and die if there were any error.
203
204=head2 stop_test_mpd();
205
206Kill the fake mpd.
207
208=head1 SEE ALSO
209
210You can look for information on this module at:
211
212=over 4
213
214=item * Search CPAN
215
216L<http://search.cpan.org/dist/Test-Corpus-Audio-MPD>
217
218=item * See open / report bugs
219
220L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-Corpus-Audio-MPD>
221
222=item * Mailing-list (same as L<Audio::MPD>)
223
224L<http://groups.google.com/group/audio-mpd>
225
226=item * Git repository
227
228L<http://github.com/jquelin/test-corpus-audio-mpd>
229
230=item * AnnoCPAN: Annotated CPAN documentation
231
232L<http://annocpan.org/dist/Test-Corpus-Audio-MPD>
233
234=item * CPAN Ratings
235
236L<http://cpanratings.perl.org/d/Test-Corpus-Audio-MPD>
237
238=back
239
240=head1 AUTHOR
241
242Jerome Quelin
243
244=head1 COPYRIGHT AND LICENSE
245
246This software is copyright (c) 2009 by Jerome Quelin.
247
248This is free software; you can redistribute it and/or modify it under
249the same terms as the Perl 5 programming language system itself.
250
251=cut
252
253
254__END__
255
256