Skip Menu |

This queue is for tickets about the Test-Smoke CPAN distribution.

Report information
The Basics
Id: 75673
Status: resolved
Priority: 0/
Queue: Test-Smoke

People
Owner: Nobody in particular
Requestors: shay [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.44
Fixed in: 1.46



Subject: [PATCH] Support sendEmail to make it easier emailing from Win32
I'm trying to set up my personal (Windows) PC to run Test-Smoke and I find that it fails at the last hurdle: it is unable to email the final smoke report. Windows doesn't have sendmail, mail or mailx, or even an SMTP server by default any more (I'm running Windows 7 Home Premium; I think there are options for installing an SMTP server on higher-spec versions of Windows 7, and on older Windows OSes, but that doesn't help me). I considered installing the non-standard hMailServer suggested here: http://social.technet.microsoft.com/forums/en-us/w7itproinstall/thread/7CEF5DA9-5B31-4B98-9BD9-9F7777DD7B37 but I think a simpler option would be to just use smtp.gmail.com :-) Unfortunately, the bundled Mail::Sendmail won't work with that as-is because Gmail requires an SSL/TLS connection (see http://support.google.com/mail/bin/answer.py?hl=en&answer=13287), and there is no IO::Socket::SSL bundled with Test-Smoke. The popular Windows command-line program called "Blat" has the same problem, so supporting that in Test-Smoke wouldn't help either. A solution to that is to have stunnel running, providing a secure connection to programs without it. I did get that running, but I've finally found a simpler solution still: there is another Windows command-line program called "sendEmail" (actually written in perl, compiled into an executable, but with the source code available too) which works very much like Blat but *does* support SSL/TLS and hence works out of the box with Gmail. The download page for sendEmail is here: http://caspian.dotconf.net/menu/Software/SendEmail/ The attached patch against Test-Smoke-1.44 adds support for this sendEmail program, thus providing an easy option for Windows users, without the hassle of setting up an SMTP server or building IO::Socket::SSL or configuring stunnel. Note that the configsmoke.pl script requests a username and password with which to connect to the specified SMTP server when using sendEmail. The password, if supplied, will be stored in plaintext format in the _config file, which is not ideal. However, you can choose to leave it empty, in which case the sendEmail program will prompt for the password at the point of sending the email, thus avoiding the need to store the password at all.
Subject: sendemail.patch
diff -ruN Test-Smoke-1.44.orig\configsmoke.pl Test-Smoke-1.44\configsmoke.pl --- Test-Smoke-1.44.orig\configsmoke.pl Fri Aug 27 19:09:28 2010 +++ Test-Smoke-1.44\configsmoke.pl Sat Mar 10 16:15:29 2012 @@ -526,6 +526,17 @@ alt => [ ], dft => 'localhost', }, + muser => { + msg => 'Which username should be used for the SMTP server?', + alt => [ ], + dft => '', + }, + mpass => { + msg => 'Which password should be used for the SMTP server?' . + "\nLeave empty to be prompted when sending email", + alt => [ ], + dft => '', + }, to => { msg => <<EOMSG, @@ -1224,6 +1235,20 @@ $config{ $arg } = prompt( $arg ); }; + /^sendemail$/ && do { + $arg = 'from'; + $config{ $arg } = prompt( $arg ); + + $arg = 'mserver'; + $config{ $arg } = prompt( $arg ); + + $arg = 'muser'; + $config{ $arg } = prompt( $arg ); + + $arg = 'mpass'; + $config{ $arg } = prompt( $arg ); + }; + /^(?:Mail::Sendmail|MIME::Lite)$/ && do { $arg = 'from'; $opt{ $arg }{chk} = '\S+'; @@ -1677,7 +1702,7 @@ qw( force_c_locale locale defaultenv ), # Report related - qw( mail mail_type mserver from to ccp5p_onfail + qw( mail mail_type mserver muser mpass from to ccp5p_onfail swcc cc swbcc bcc ), # Archive reports and logfile @@ -2171,6 +2196,8 @@ local $ENV{PATH} = "$ENV{PATH}$Config{path_sep}/usr/sbin"; $map{ $mailer } = whereis( $mailer ); } + $mailer = 'sendemail'; + $map{ $mailer } = whereis( $mailer ); eval { require Mail::Sendmail }; $map{ 'Mail::Sendmail' } = $@ ? '' : 'Mail::Sendmail'; diff -ruN Test-Smoke-1.44.orig\lib\Test\Smoke\Mailer.pm Test-Smoke-1.44\lib\Test\Smoke\Mailer.pm --- Test-Smoke-1.44.orig\lib\Test\Smoke\Mailer.pm Fri Aug 27 19:09:28 2010 +++ Test-Smoke-1.44\lib\Test\Smoke\Mailer.pm Sat Mar 10 16:12:50 2012 @@ -27,12 +27,14 @@ mail => [qw( bcc cc mailbin )], df_mailxbin => 'mailx', mailx => [qw( bcc cc mailxbin swcc swbcc )], + df_sendemailbin => 'sendemail', + sendemail => [qw( from bcc cc sendemailbin mserver muser mpass )], df_sendmailbin => 'sendmail', sendmail => [qw( from bcc cc sendmailbin )], 'Mail::Sendmail' => [qw( from bcc cc mserver )], 'MIME::Lite' => [qw( from bcc cc mserver )], - valid_mailer => { sendmail => 1, mail => 1, mailx => 1, + valid_mailer => { sendmail => 1, mail => 1, mailx => 1, sendemail => 1, 'Mail::Sendmail' => 1, 'MIME::Lite' => 1, }, ); @@ -51,7 +53,7 @@ =head1 DESCRIPTION -This little wrapper still allows you to use the B<sendmail>, +This little wrapper still allows you to use the B<sendmail>, B<sendemail>, B<mail> or B<mailx> programs, but prefers to use the B<Mail::Sendmail> module (which comes with this distribution) to send the reports. @@ -63,7 +65,7 @@ Can we provide sensible defaults for the mail stuff? - mhowto => [Module::Name|sendmail|mail|mailx] + mhowto => [Module::Name|sendmail|mail|mailx|sendemail] mserver => an SMTP server || localhost mbin => the full path to the mail binary mto => list of addresses (comma separated!) @@ -101,6 +103,7 @@ /^sendmail$/ && return Test::Smoke::Mailer::Sendmail->new( %fields ); /^mailx?$/ && return Test::Smoke::Mailer::Mail_X->new( %fields ); + /^sendemail?$/ && return Test::Smoke::Mailer::SendEmail->new( %fields ); /^Mail::Sendmail$/ && return Test::Smoke::Mailer::Mail_Sendmail->new( %fields ); /^MIME::Lite$/ && @@ -119,15 +122,15 @@ sub fetch_report { my $self = shift; - my $report_file = File::Spec->catfile( $self->{ddir}, $self->{rptfile} ); + $self->{file} = File::Spec->catfile( $self->{ddir}, $self->{rptfile} ); local *REPORT; - if ( open REPORT, "< $report_file" ) { + if ( open REPORT, "< $self->{file}" ) { $self->{body} = do { local $/; <REPORT> }; close REPORT; } else { require Carp; - Carp::croak( "Cannot read '$report_file': $!" ); + Carp::croak( "Cannot read '$self->{file}': $!" ); } my @config = parse_report_Config( $self->{body} ); @@ -336,6 +339,80 @@ $self->{error} = "Error in pipe to '$mailer': $! (" . $?>>8 . ")"; } else { $self->{error} = "Cannot fork '$mailer': $!"; + } + $self->{v} and print $self->{error} ? "not OK\n" : "OK\n"; + + return ! $self->{error}; +} + +=back + +=head1 Test::Smoke::Mailer::SendEmail + +This handles sending the message with the B<sendEmail> program. + +=over 4 + +=cut + +package Test::Smoke::Mailer::SendEmail; + +@Test::Smoke::Mailer::SendEmail::ISA = qw( Test::Smoke::Mailer ); + +=item Test::Smoke::Mailer::SendEmail->new( %args ) + +Keys for C<%args>: + + * ddir + * mserver + * muser + * mpass + * sendemailbin + * to + * from + * cc + * v + +=cut + +sub new { + my $proto = shift; + my $class = ref $proto || $proto; + + return bless { @_ }, $class; +} + +=item $mailer->mail( ) + +C<mail()> sets up the commandline and body and passes it to the +B<sendemail> program. + +=cut + +sub mail { + my $self = shift; + + my $mailer = $self->{sendemailbin}; + + my $subject = $self->fetch_report(); + my $cc = $self->_get_cc( $subject ); + + my $cmdline = qq|$mailer -u "$subject"|; + $self->{swcc} ||= '-cc', $cmdline .= qq| $self->{swcc} "$cc"| if $cc; + $self->{swbcc} ||= '-bcc', $cmdline .= qq| $self->{swbcc} "$self->{bcc}"| + if $self->{bcc}; + $cmdline .= qq| -t "$self->{to}"|; + $cmdline .= qq| -f "$self->{from}"| if $self->{from}; + $cmdline .= qq| -s "$self->{mserver}"| if $self->{mserver}; + $cmdline .= qq| -xu "$self->{muser}"| if $self->{muser}; + $cmdline .= qq| -xp "$self->{mpass}"| if ($self->{mpass}); + $cmdline .= qq| -o message-file="$self->{file}"|; + + $self->{v} > 1 and print "[$cmdline]\n"; + $self->{v} and print "Sending report to $self->{to}\n"; + system $cmdline; + if ($?) { + $self->{error} = "Error executing '$mailer': " . $?>>8; } $self->{v} and print $self->{error} ? "not OK\n" : "OK\n"; diff -ruN Test-Smoke-1.44.orig\mailrpt.pl Test-Smoke-1.44\mailrpt.pl --- Test-Smoke-1.44.orig\mailrpt.pl Fri Aug 27 19:09:28 2010 +++ Test-Smoke-1.44\mailrpt.pl Sat Mar 10 15:47:20 2012 @@ -29,6 +29,8 @@ ccp5p_onfail => undef, from => undef, mserver => undef, + muser => undef, + mpass => undef, v => undef, rptfile => 'mktest.rpt', @@ -42,7 +44,7 @@ my $defaults = Test::Smoke::Mailer->config( 'all_defaults' ); -my %valid_type = map { $_ => 1 } qw( mail mailx sendmail +my %valid_type = map { $_ => 1 } qw( mail mailx sendmail sendemail Mail::Sendmail MIME::Lite ); =head1 NAME @@ -76,7 +78,8 @@ --to <emailaddresses> Comma separated list (smokers-reports@perl.org) --cc <emailaddresses> Comma separated list - -t | --type <type> mail mailx sendmail Mail::Sendmail [mandatory] + -t | --type <type> mail mailx sendmail sendemail Mail::Sendmail + [mandatory] --nomail Don't send the message --report Create a report anyway @@ -96,6 +99,13 @@ --from <address> +=item * B<options for> -t sendemail + + --from <address> + --mserver <smtpserver> (localhost) + --muser <smtpserverusername> + --mpass <smtpserverpassword> + =item * B<options for> -t Mail::Sendmail | MIME::Lite --from <address> @@ -114,7 +124,7 @@ 'type|t=s', 'ddir|d=s', 'to=s', 'cc=s', 'bcc=s', 'ccp5p_onfail!', 'v|verbose=i', - 'from=s', 'mserver=s', + 'from=s', 'mserver=s', 'muser=s', 'mpass=s', 'help|h', 'man',
Integrated. -- Abe.