File Coverage

blib/lib/Test/SFTP.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1 3     3   92191 use strict;
  3         7  
  3         107  
2 3     3   15 use warnings;
  3         5  
  3         144  
3             package Test::SFTP;
4             {
5             $Test::SFTP::VERSION = '1.10';
6             }
7             # ABSTRACT: An object to help test SFTPs
8              
9 3     3   28 use Carp;
  3         17  
  3         289  
10 3     3   121865 use Moose;
  0            
  0            
11             use English '-no_match_vars';
12             use Test::Builder;
13             use Net::SFTP::Foreign;
14             use namespace::autoclean;
15              
16             use parent 'Test::Builder::Module';
17              
18             # variables for the connection
19             has 'host' => ( is => 'ro', isa => 'Str', required => 1 );
20             has 'user' => ( is => 'ro', isa => 'Str' );
21             has 'password' => ( is => 'ro', isa => 'Str' );
22              
23             has 'debug' => ( is => 'ro', isa => 'Int', default => 0 );
24             has 'port' => ( is => 'ro', isa => 'Int' );
25             has 'timeout' => ( is => 'ro', isa => 'Int' );
26             has 'more' => ( is => 'ro', isa => 'ArrayRef' );
27              
28             # this holds the object itself. that way, users can do:
29             # $t_sftp->object->get() in a raw manner if they want
30             has 'object' => (
31             is => 'rw',
32             isa => 'Net::SFTP::Foreign',
33             lazy_build => 1,
34             );
35              
36             has 'connected' => ( is => 'rw', isa => 'Bool', default => 0 );
37              
38             my $CLASS = __PACKAGE__;
39              
40             sub _build_object {
41             my $self = shift;
42             my @more = ();
43             my %opts = ();
44              
45             $self->user and $opts{'user'} = $self->user;
46             $self->password and $opts{'password'} = $self->password;
47             $self->more and push @more, @{ $self->more };
48             $self->debug and push @more, '-v';
49              
50             if ( my $timeout = $self->timeout ) {
51             $opts{'timeout'} = $timeout;
52             push @more, '-o', "ConnectTimeout=$timeout";
53             }
54              
55             my $object = Net::SFTP::Foreign->new(
56             host => $self->host,
57             more => \@more,
58             %opts,
59             );
60              
61             $object->error ? $self->connected(0) : $self->connected(1);
62              
63             return $object;
64             }
65              
66             sub BUILD {
67             my $self = shift;
68             my $EMPTY = q{};
69             $self->object;
70             }
71              
72             sub can_connect {
73             my ( $self, $test ) = @_;
74             my $tb = $CLASS->builder;
75              
76             $self->object( $self->_build_object );
77             $tb->ok( ! $self->object->error(), $test );
78             }
79              
80             sub cannot_connect {
81             my ( $self, $test ) = @_;
82             my $tb = $CLASS->builder;
83              
84             $self->object( $self->_build_object );;
85             $tb->ok( $self->object->error, $test );
86             }
87              
88             sub is_status {
89             my ( $self, $status, $test ) = @_;
90             my $tb = $CLASS->builder;
91              
92             $tb->is_eq( $self->object->status, $status, $test );
93             }
94              
95             sub is_error {
96             my ( $self, $error, $test ) = @_;
97             my $tb = $CLASS->builder;
98              
99             $tb->is_eq( $self->object->error, $error, $test );
100             }
101              
102             sub can_get {
103             my ( $self, $local, $remote, $test ) = @_;
104             my $tb = $CLASS->builder;
105             my $EMPTY = q{};
106              
107             $self->connected || $self->connect;
108              
109             $tb->ok( $self->object->get( $local, $remote ), $test );
110             }
111              
112             sub cannot_get {
113             my ( $self, $local, $remote, $test ) = @_;
114             my $tb = $CLASS->builder;
115              
116             $self->connected || $self->connect;
117              
118             $tb->ok( !$self->object->get( $local, $remote ), $test );
119             }
120              
121             sub can_put {
122             my ( $self, $local, $remote, $test ) = @_;
123             my $tb = $CLASS->builder;
124              
125             $self->connected || $self->connect;
126              
127             my $eval_error = eval { $self->object->put( $local, $remote ); };
128             $tb->ok( $eval_error, $test );
129             }
130              
131             sub cannot_put {
132             my ( $self, $local, $remote, $test ) = @_;
133             my $tb = $CLASS->builder;
134              
135             $self->connected || $self->connect;
136              
137             my $eval_error = eval { $self->object->put( $local, $remote ); };
138             $tb->ok( !$eval_error, $test );
139             }
140              
141             sub can_ls {
142             my ( $self, $path, $test ) = @_;
143             my $tb = $CLASS->builder;
144             $self->connected || $self->connect;
145             my $eval_error = eval { $self->object->ls($path); };
146             $tb->ok( $eval_error, $test );
147             }
148              
149             sub cannot_ls {
150             my ( $self, $path, $test ) = @_;
151             my $tb = $CLASS->builder;
152             $self->connected || $self->connect;
153             my $eval_error = eval { $self->object->ls($path); };
154             $tb->ok( !$eval_error, $test );
155             }
156              
157             no Moose;
158              
159             1;
160              
161              
162              
163             =pod
164              
165             =head1 NAME
166              
167             Test::SFTP - An object to help test SFTPs
168              
169             =head1 VERSION
170              
171             version 1.10
172              
173             =head1 SYNOPSIS
174              
175             use Test::SFTP;
176              
177             my $t_sftp = Test::SFTP->new(
178             host => 'localhost',
179             user => 'sawyer',
180             password => '2o7U!OYv',
181             ...
182             );
183              
184             $t_sftp->can_get( $remote_path, $local_path, "Getting $remote_path" );
185              
186             $t_sftp->can_put(
187             $local_path,
188             $remote_path,
189             "Trying to copy $local_path to $remote_path",
190             );
191              
192             =head1 DESCRIPTION
193              
194             Unlike most testing frameworks, I<Test::SFTP> provides an object oriented
195             interface. The reason is that it's simply easier to use an object than throw the
196             login information as command arguments each time.
197              
198             =head1 ATTRIBUTES
199              
200             Most attributes (at least those you can set on initialization) are read-only.
201             That means they cannot be set after the object was already created.
202              
203             $t_sftp->new(
204             host => 'localhost',
205             user => 'root'
206             password => 'p455w0rdZ'
207             debug => 1 # default: 0
208             more => [ qw( -o PreferredAuthentications=password ) ]
209             timeout => 10 # 10 seconds timeout for the connection
210             );
211              
212             =head2 host
213              
214             The host you're connecting to.
215              
216             =head2 user
217              
218             Username you're connecting with.
219              
220             If you do not specify this explicitly, it will use the user who is running
221             the application.
222              
223             =head2 password
224              
225             Password for the username you're connecting with.
226              
227             If you do not specify this explicitly, it will try other connection methods
228             such as SSH keys.
229              
230             =head2 port
231              
232             Port you're connecting to.
233              
234             =head2 debug
235              
236             This flag turns on verbose for I<Net::SFTP::Foreign>.
237              
238             =head2 more
239              
240             SSH arguments, such as used in I<Net::SFTP::Foreign>, I<Net::OpenSSH> or plain
241             OpenSSH.
242              
243             =head2 timeout
244              
245             This turns on both connection timeout (via I<-o ConnectTimeout=$time>) for ssh
246             and a timeout for every data request.
247              
248             It is recommended to set a timeout, or the test might hang for a very long time
249             if the target is unavailable.
250              
251             =head2 Sensitive Attributes
252              
253             =over 4
254              
255             =item connected
256              
257             A boolean attribute to note whether the I<Net::SFTP::Foreign> object is
258             connected.
259              
260             Most methods used need the object to be connected. This attribute is used
261             internally to check if it's not connected yet, and if it isn't, it reconnect.
262              
263             You can use this attribute to check whether it's connected internally in your
264             test script or run it using I<< $t_sftp->is_connected >> as a test.
265              
266             However, try not to set this attribute.
267              
268             =item C<< $t_sftp->object($object) >>
269              
270             This holds the object of I<Net::SFTP::Foreign>. It's there to allow users more
271             fingergrain access to the object. With that, you can do:
272              
273             is(
274             $t_sftp->object->some_method( ... ),
275             'Specific test not covered in the framework',
276             );
277              
278             Please refer to L<Net::SFTP::Foreign> for all the attributes and methods it
279             supports.
280              
281             =back
282              
283             =head1 SUBROUTINES/METHODS
284              
285             =head2 $t_sftp->can_connect($test_name)
286              
287             Checks whether we were able to connect to the machine.
288              
289             =head2 $t_sftp->cannot_connect($test_name)
290              
291             Checks whether we were B<not> able to connect to the machine.
292              
293             =head2 $t_sftp->is_status( $string , $test_name )
294              
295             Checks the status code returned from the SFTP server.
296              
297             This is practicely the FX2TXT.
298              
299             =head2 $t_sftp->is_error( $string , $test_name )
300              
301             Checks for a certain SFTP error existing.
302              
303             =head2 $t_sftp->can_get( $remote, $local, $test_name )
304              
305             Checks whether we're able to get a file from C<$remote> to C<$local>.
306              
307             =head2 $t_sftp->cannot_get( $remote, $local, $test_name )
308              
309             Checks whether we're unable to get a file from C<$remote> to C<$local>.
310              
311             =head2 $t_sftp->can_put( $local, $remote, $test_name )
312              
313             Checks whether we're able to upload a file from C<$local> to C<$remote>.
314              
315             =head2 $t_sftp->cannot_put( $local, $remote, $test_name )
316              
317             Checks whether we're unable to upload a file from C<$local> to C<$remote>.
318              
319             =head2 $t_sftp->can_ls( $path, $test_name )
320              
321             Checks whether we're able to ls a folder or file. Can be used to check the
322             existence of files or folders.
323              
324             =head2 $t_sftp->cannot_ls( $path, $test_name )
325              
326             Checks whether we're unable to ls a folder or file. Can be used to check the
327             nonexistence of files or folders.
328              
329             =head2 BUILD
330              
331             Internal L<Moose> function used to initialize the object. Do not touch. :)
332              
333             =head1 DEPENDENCIES
334              
335             L<Moose>
336              
337             L<Expect>
338              
339             L<IO::Pty>
340              
341             L<Net::SFTP::Foreign>.
342              
343             L<Test::Builder>
344              
345             L<namespace::autoclean>
346              
347             L<parent>
348              
349             =head1 DIAGNOSTICS
350              
351             You can use the B<object> attribute to access the I<Net::SFTP::Foreign> object
352             directly.
353              
354             =head1 CONFIGURATION AND ENVIRONMENT
355              
356             Some tests in the module require creating and removing files. As long as we
357             don't have complete control over the environment we're going to connect to, it's
358             hard to know if we're gonna upload a file that perhaps already exists already.
359             We try hard to avoid it by creating a file with a random number as the filename.
360              
361             So, in previous versions (actually, only 1), these tests were mixed with all the
362             other tests so if you had set the environment variable to testing, it would test
363             it with everything. If you don't, it would not test a bunch of other tests that
364             aren't dangerous at all.
365              
366             To ask for this to be tested as well, set the environment variable
367             TEST_SFTP_DANG.
368              
369             =head1 INCOMPATIBILITIES
370              
371             The default backend in L<Net::SFTP::Foreign> uses L<Expect> for password
372             authentication. Unfortunately, on windows, it only works using Cygwin Perl.
373              
374             So, if you're using Windows and need password authentication, you might want to
375             use I<plink> instead of OpenSSH SSH client or the Net_SSH2 backend.
376              
377             =head1 BUGS AND LIMITATIONS
378              
379             This module will have the same limitations that exist for
380             I<Net::SFTP::Foreign>, though probably more.
381              
382             Please report any bugs or feature requests to C<bug-test-sftp at rt.cpan.org>,
383             or through the web interface at
384             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-SFTP>. I will be
385             notified, and then you'll automatically be notified of progress on your bug as I
386             make changes.
387              
388             =head1 SUPPORT
389              
390             You can find documentation for this module with the perldoc command.
391              
392             perldoc Test::SFTP
393              
394             You can also look for information at:
395              
396             =over 4
397              
398             =item * RT: CPAN's request tracker
399              
400             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-SFTP>
401              
402             =item * AnnoCPAN: Annotated CPAN documentation
403              
404             L<http://annocpan.org/dist/Test-SFTP>
405              
406             =item * CPAN Ratings
407              
408             L<http://cpanratings.perl.org/d/Test-SFTP>
409              
410             =item * Search CPAN
411              
412             L<http://search.cpan.org/dist/Test-SFTP/>
413              
414             =back
415              
416             =head1 ACKNOWLEDGEMENTS
417              
418             Salvador Fandiño García for L<Net::SFTP::Foreign>, L<Net::OpenSSH>, being a
419             responsive dedicated author and a really nice guy! :)
420              
421             =head1 AUTHOR
422              
423             Sawyer X <xsawyerx@cpan.org>
424              
425             =head1 COPYRIGHT AND LICENSE
426              
427             This software is copyright (c) 2011 by Sawyer X.
428              
429             This is free software; you can redistribute it and/or modify it under
430             the same terms as the Perl 5 programming language system itself.
431              
432             =cut
433              
434              
435             __END__
436