httpd-test-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r122807 - in httpd/test/trunk/perl-framework/Apache-Test: . Apache-TestItSelf Apache-TestItSelf/Apache-TestMe Apache-TestItSelf/Apache-TestMe/t Apache-TestItSelf/Apache-TestMe/t/basic Apache-TestItSelf/Apache-TestMe/t/conf Apache-TestItSelf/Apache-TestMe/t/response Apache-TestItSelf/Apache-TestMe/t/response/TestBasic Apache-TestItSelf/lib Apache-TestItSelf/lib/MyTest Apache-TestItSelf/sample Apache-TestItSelf/t
Date Mon, 20 Dec 2004 04:06:55 GMT
Author: stas
Date: Sun Dec 19 20:06:54 2004
New Revision: 122807

URL: http://svn.apache.org/viewcvs?view=rev&rev=122807
Log:
add Apache-TestItSelf and Apache-TestMe sub-projects.

Added:
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Changes
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Makefile.PL
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/README
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/TEST.PL
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/hello.t
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/modperl_extra.pl
  (contents, props changed)
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Hello.pm
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Changes
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Makefile.PL
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/README
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/lib/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/Util.pm
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache2_modules_testitself_config.pm
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache_test_config.pm
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/modperl2_testitself_config.pm
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/TEST.PL
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/httpd_arg.t
   httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/interactive.t
Modified:
   httpd/test/trunk/perl-framework/Apache-Test/Changes
   httpd/test/trunk/perl-framework/Apache-Test/META.yml
   httpd/test/trunk/perl-framework/Apache-Test/Makefile.PL

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Changes
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Changes?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Changes	Sun
Dec 19 20:06:54 2004
@@ -0,0 +1,17 @@
+=head1 NAME
+
+Changes - Apache::TestMe changes logfile
+
+=head1 Changes
+
+=over 4
+
+=item 0.01
+
+write a basic mod_perl test: basic/hello.t
+
+starting the config test suite used by Apache::TestItSelf
+
+=back
+
+=cut
\ No newline at end of file

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Makefile.PL
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Makefile.PL?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/Makefile.PL
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,217 @@
+use 5.005;
+
+use lib qw(../../lib); # Apache-Test/lib
+
+use Apache::TestMM qw(test clean);
+use Apache::TestMM ();
+use Apache::TestReport;
+
+use ExtUtils::MakeMaker ();
+
+my $mp_gen = satisfy_mp_generation();
+warn "Goind to build against mod_perl/$mod_perl::VERSION Perl/$]\n";
+
+Apache::TestMM::filter_args();
+
+my @scripts = qw(t/TEST);
+for (@scripts) {
+    Apache::TestMM::generate_script($_);
+}
+Apache::TestReport->generate_script;
+
+my @clean_files = (@scripts, qw(t/REPORT));
+
+
+my %common_opts = (
+    NAME      => 'Apache-TestMe',
+    VERSION   => '0.01',
+    clean     => {
+        FILES => "@clean_files",
+    },
+);
+
+if ($mp_gen == 1) {
+    require ExtUtils::MakeMaker;
+    ExtUtils::MakeMaker::WriteMakefile(
+        %common_opts,
+    );
+
+}
+else {
+    require Apache2;
+    require ModPerl::MM;
+    ModPerl::MM::WriteMakefile(
+        %common_opts,
+    );
+}
+# If a specific generation was passed as an argument,
+#     if satisfied
+#         return the same generation
+#     else
+#         die
+# else @ARGV and %ENV will be checked for specific orders
+#     if the specification will be found
+#         if satisfied
+#             return the specified generation
+#         else
+#             die
+#     else if any mp generation is found
+#              return it
+#           else
+#              die
+
+sub satisfy_mp_generation {
+    my $wanted = shift || wanted_mp_generation();
+
+    unless ($wanted == 1 || $wanted == 2) {
+        die "don't know anything about mod_perl generation: $wanted\n" .
+            "currently supporting only generations 1 and 2";
+    }
+
+    my $selected = 0;
+
+    if ($wanted == 1) {
+        require_mod_perl();
+        if ($mod_perl::VERSION >= 1.99) {
+            # so we don't pick 2.0 version if 1.0 is wanted
+            die "You don't seem to have mod_perl 1.0 installed";
+        }
+        $selected = 1;
+    }
+    elsif ($wanted == 2) {
+        #warn "Looking for mod_perl 2.0";
+        require Apache2;
+        require_mod_perl();
+        if ($mod_perl::VERSION < 1.99) {
+            die "You don't seem to have mod_perl 2.0 installed";
+        }
+        $selected = 2;
+    }
+    else {
+        require_mod_perl();
+        $selected = $mod_perl::VERSION >= 1.99 ? 2 : 1;
+        warn "Using $mod_perl::VERSION\n";
+    }
+
+    return $selected;
+}
+
+sub require_mod_perl {
+    eval { require mod_perl };
+    die "Can't find mod_perl installed\nThe error was: $@" if $@;
+}
+
+
+# the function looks at %ENV and Makefile.PL option to figure out
+# whether a specific mod_perl generation was requested.
+# It uses the following logic:
+# via options:
+# perl Makefile.PL MOD_PERL=2
+# or via %ENV:
+# env MOD_PERL=1 perl Makefile.PL
+#
+# return value is:
+# 1 or 2 if the specification was found (mp 1 and mp 2 respectively)
+# 0 otherwise
+sub wanted_mp_generation {
+
+    # check if we have a command line specification
+    # flag: 0: unknown, 1: mp1, 2: mp2
+    my $flag = 0;
+    my @pass;
+    while (@ARGV) {
+        my $key = shift @ARGV;
+        if ($key =~ /^MOD_PERL=(\d)$/) {
+            $flag = $1;
+        }
+        else {
+            push @pass, $key;
+        }
+    }
+    @ARGV = @pass;
+
+    # check %ENV
+    my $env = exists $ENV{MOD_PERL} ? $ENV{MOD_PERL} : 0;
+
+    # check for contradicting requirements
+    if ($env && $flag && $flag != $env) {
+        die <<EOF;
+Can\'t decide which mod_perl version should be used, since you have
+supplied contradicting requirements:
+    enviroment variable MOD_PERL=$env
+    Makefile.PL option  MOD_PERL=$flag
+EOF
+    }
+
+    my $wanted = 0; 
+    $wanted = 2 if $env == 2 || $flag == 2;
+    $wanted = 1 if $env == 1 || $flag == 1;
+
+    unless ($wanted) {
+        # if still unknown try to require mod_perl.pm
+        eval { require mod_perl };
+        unless ($@) {
+            $wanted = $mod_perl::VERSION >= 1.99 ? 2 : 1;
+        }
+    }
+
+    return $wanted;
+}
+
+
+# the function looks at %ENV and Makefile.PL option to figure out
+# whether a specific mod_perl generation was requested.
+# It uses the following logic:
+# via options:
+# perl Makefile.PL MOD_PERL=2
+# or via %ENV:
+# env MOD_PERL=1 perl Makefile.PL
+#
+# return value is:
+# 1 or 2 if the specification was found (mp 1 and mp 2 respectively)
+# 0 otherwise
+sub wanted_mp_generation {
+
+    # check if we have a command line specification
+    # flag: 0: unknown, 1: mp1, 2: mp2
+    my $flag = 0;
+    my @pass;
+    while (@ARGV) {
+        my $key = shift @ARGV;
+        if ($key =~ /^MOD_PERL=(\d)$/) {
+            $flag = $1;
+        }
+        else {
+            push @pass, $key;
+        }
+    }
+    @ARGV = @pass;
+
+    # check %ENV
+    my $env = exists $ENV{MOD_PERL} ? $ENV{MOD_PERL} : 0;
+
+    # check for contradicting requirements
+    if ($env && $flag && $flag != $env) {
+        die <<EOF;
+Can\'t decide which mod_perl version should be used, since you have
+supplied contradicting requirements:
+    enviroment variable MOD_PERL=$env
+    Makefile.PL option  MOD_PERL=$flag
+EOF
+    }
+
+    my $wanted = 0;
+    $wanted = 2 if $env == 2 || $flag == 2;
+    $wanted = 1 if $env == 1 || $flag == 1;
+
+    unless ($wanted) {
+        # if still unknown try to require mod_perl.pm
+        eval { require mod_perl };
+        unless ($@) {
+            $wanted = $mod_perl::VERSION >= 1.99 ? 2 : 1;
+        }
+    }
+
+    return $wanted;
+}
+

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/README
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/README?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/README	Sun
Dec 19 20:06:54 2004
@@ -0,0 +1,5 @@
+This package contains an Apache-Test test suite used by
+Apache-TestItSelf. We use a dedicated test suite, so we can re-create
+cases which normally won't fit into the core Apache-Test test suite.
+This is the test suite that should be run from Apache-TestTestItSelf
+as explained in Apache-TestItSelf/README

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/TEST.PL
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/TEST.PL?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/TEST.PL
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,37 @@
+use strict;
+
+use FindBin;
+# test against the A-T source lib for easier dev
+use lib "$FindBin::Bin/../../../lib";
+
+use lib qw(lib ../lib);
+
+use warnings FATAL => 'all';
+
+use Apache::TestRunPerl ();
+
+package MyTest;
+
+use vars qw(@ISA);
+@ISA = qw(Apache::TestRunPerl);
+
+sub new_test_config {
+    my $self = shift;
+
+    #$self->{conf_opts}->{authname}      = 'gold club';
+
+    return $self->SUPER::new_test_config;
+}
+
+sub bug_report {
+    my $self = shift;
+
+    print <<EOI;
++-----------------------------------------------------+
+| To report problems please refer to the SUPPORT file |
++-----------------------------------------------------+
+EOI
+}
+
+MyTest->new->run(@ARGV);
+

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/hello.t
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/hello.t?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/basic/hello.t
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,20 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 3, have_lwp;
+
+my $response = GET '/TestBasic__Hello';
+
+ok t_cmp $response->code, 200, '/handler returned HTTP_OK';
+
+ok t_cmp $response->header('Content-Type'), 'text/plain',
+    '/handler set proper Content-Type';
+
+chomp(my $content = $response->content);
+
+ok t_cmp $content, 'Hello', '/handler returned proper content';
+

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/modperl_extra.pl
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/modperl_extra.pl?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/conf/modperl_extra.pl
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,2 @@
+
+1;

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Hello.pm
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Hello.pm?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Apache-TestMe/t/response/TestBasic/Hello.pm
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,19 @@
+package TestBasic::Hello;
+
+use Apache::RequestRec ();
+use Apache::RequestIO ();
+use Apache::Const -compile => qw(OK);
+
+# XXX: adjust the test that it'll work under mp1 as well
+
+sub handler {
+
+  my $r = shift;
+
+  $r->content_type('text/plain');
+  $r->print('Hello');
+
+  return Apache::OK;
+}
+
+1;

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Changes
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Changes?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Changes	Sun Dec 19 20:06:54
2004
@@ -0,0 +1,20 @@
+=head1 NAME
+
+Changes - Apache::TestItSelf changes logfile
+
+=head1 Changes
+
+=over 4
+
+=item 0.01
+
+new test: interactive.t: the interactive config 
+
+new test: httpd_arg.t: passing -httpd argument to 'perl Makefile.PL'
+and to 't/TEST'
+
+starting the config test suite
+
+=back
+
+=cut
\ No newline at end of file

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Makefile.PL
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Makefile.PL?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/Makefile.PL	Sun Dec 19 20:06:54
2004
@@ -0,0 +1,40 @@
+use 5.005;
+
+use lib qw(../lib); # Apache-Test/lib
+use Apache::Test5005compat;
+
+use strict;
+use warnings;
+
+use ExtUtils::MakeMaker;
+
+use Apache::TestMM ();
+
+Apache::TestMM::generate_script('t/TEST');
+
+my @clean_files =
+    qw(t/TEST
+       Makefile.old
+      );
+
+my %prereq = (
+    # needed to be able to use one perl version to drive the test
+    # suite, but a different version from the tests themselves
+    'Test::Harness' => '2.44',
+);
+
+WriteMakefile(
+    NAME      => 'Apache::TestItSelf',
+    PREREQ_PM => \%prereq,
+    VERSION   => "0.01",
+    NORECURS  => 1, # don't descend into Apache-TestMe
+
+    dist      => {
+        COMPRESS => 'gzip -9f', SUFFIX=>'gz',
+    },
+    clean     => {
+        FILES => "@clean_files",
+    },
+);
+
+

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/README
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/README?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/README	Sun Dec 19 20:06:54
2004
@@ -0,0 +1,73 @@
+This test suite tests various Apache-Test setups (i.e. whether the
+configuration works correctly), something that can't be tested with
+the normal run-time test suite.
+
+1) first of all move into Apache-TestItSelf
+
+  % chdir Apache-TestItSelf
+
+
+
+2) now choose which test suite to run again, to test whether some
+  changes in A-T break its config, run 2a. But if the config testing
+  coverage is not complete, try other test suites and then try to
+  re-create this problem in 2a.
+
+  You will need to adjust config files under sample/ to reflect the
+  location of your preinstalled httpd and mod_perl files.
+
+  a. Apache-Test config test suite
+
+  % t/TEST -config sample/apache_test_config.pm
+
+  this runs against the test suite under:
+
+  Apache-Test/Apache-TestItSelf/Apache-TestMe/t
+
+  it's the same as calling:
+
+  % t/TEST -base ~/apache.org/Apache-Test/Apache-TestItSelf/Apache-TestMe/t \
+  -config sample/apache_test_config.pm
+
+
+
+  b. Apache-Test
+
+  assuming that Apache-Test is checked out under
+  ~/apache.org/Apache-Test, the following will run the tests against the
+  Apache-Test test suite
+
+  % t/TEST -base ~/apache.org/Apache-Test \
+  -config sample/apache_test_config.pm
+
+
+
+  c. modperl-2.0
+
+  assuming that modperl-2.0 is checked out under
+  ~/apache.org/modperl-2.0, the following will run the tests against the
+  modperl-2.0 test suite
+
+  % t/TEST -base ~/apache.org/mp2-svn \
+  -config sample/modperl2_testitself_config.pm httpd_arg.t interactive.t
+
+
+
+  d. 3rd party modules ###
+
+  assuming that Apache-VMonitor-2.0 is checked out under
+  ~/work/modules/Apache-VMonitor-2.0, the following will run the tests
+  against the Apache-VMonitor-2.0 test suite. of course any other 3rd
+  party module should do.
+
+
+  % t/TEST -base ~/work/modules/Apache-VMonitor-2.0 \
+  -config sample/apache2_modules_testitself_config.pm
+
+
+-----------------------------
+
+DEBUGGING:
+
+env IPCRUNDEBUG=data t/TEST t/interactive.t
+(for more options see IPC::Run / IPC::Run3 manpages)

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/Util.pm
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/Util.pm?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/lib/MyTest/Util.pm	Sun Dec
19 20:06:54 2004
@@ -0,0 +1,160 @@
+package MyTest::Util;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::TestConfig;
+use Apache::TestTrace;
+
+use Exporter ();
+use IPC::Run3 ();
+use Cwd;
+
+use vars qw(@ISA @EXPORT @EXPORT_OK);
+@ISA = qw(Exporter);
+@EXPORT    = ();
+@EXPORT_OK = qw(myrun3 go_in go_out work_dir dump_stds check_eval
+                test_configs);
+
+sub myrun3 {
+    my $cmd = shift;
+    my $out = '';
+    my $err = '';
+
+    my $ok = IPC::Run3::run3($cmd, \undef, \$out, \$err);
+    die "IPC::Run3 failed to run $cmd" unless $ok;
+
+    dump_stds($cmd, '', $out, $err) if $?;
+
+    return ($out, $err);
+}
+
+sub go_in {
+    my $orig_dir = cwd();
+    my $dir = $ENV{APACHE_TESTITSELF_BASE_DIR} || '';
+    debug "chdir $dir";
+    chdir $dir or die "failed to chdir to $dir: $!";
+    return $orig_dir;
+}
+
+sub go_out {
+    my $dir = shift;
+    debug "chdir $dir";
+    chdir $dir or die "failed to chdir to $dir: $!";
+}
+
+# the base dir from which the A-T tests are supposed to be run
+# we might not be there
+sub work_dir { $ENV{APACHE_TESTITSELF_BASE_DIR} }
+
+sub dump_stds {
+    my($cmd, $in, $out, $err) = @_;
+    $cmd = 'unknown' unless length $cmd;
+    $in  = '' unless length $in;
+    $out = '' unless length $out;
+    $err = '' unless length $err;
+
+    if ($cmd) {
+        $cmd =~ s/\n$//;
+        $cmd =~ s/^/# /gm;
+        print STDERR "\n\n#== CMD ===\n$cmd\n#=============";
+    }
+    if ($in) {
+        $in =~ s/\n$//;
+        $in =~ s/^/# /gm;
+        print STDERR "\n### STDIN  ###\n$in\n##############\n\n\n";
+    }
+    if ($out) {
+        $out =~ s/\n$//;
+        $out =~ s/^/# /gm;
+        print STDERR "\n### STDOUT ###\n$out\n##############\n\n\n";
+    }
+    if ($err) {
+        $err =~ s/\n$//;
+        $err =~ s/^/# /gm;
+        print STDERR "\n### STDERR ###\n$err\n##############\n\n\n";
+    }
+}
+
+# if $@ is set dumps the $out and $err streams and dies
+# otherwise resets the $out and $err streams if $reset_std is true
+sub check_eval {
+    my($cmd, $out, $err, $reset_std, $msg) = @_;
+    $msg ||= "unknown";
+    if ($@) {
+        dump_stds($cmd, '', $out, $err);
+        die "$@\nError: $msg\n";
+    }
+    # reset the streams in caller
+    ($_[1], $_[2]) = ("", "") if $reset_std;
+}
+
+# this function returns an array of configs (hashes) coming from
+# -config-file command line option
+sub test_configs {
+    my $config_file = $ENV{APACHE_TESTITSELF_CONFIG_FILE} || '';
+
+    # reset
+    %Apache::TestItSelf::Config = ();
+    @Apache::TestItSelf::Configs = ();
+
+    require $config_file;
+    unless (@Apache::TestItSelf::Configs) {
+        error "can't find test configs in '$config_file'";
+        exit 1;
+    }
+
+    my %global = %Apache::TestItSelf::Config;
+
+    # merge the global config with instance configs
+    my @configs = map { { %global, %$_ } } @Apache::TestItSelf::Configs;
+
+    return @configs;
+}
+
+
+1;
+
+__END__
+
+=head1 NAME
+
+MyTest::Util -- helper functions
+
+=head1 Config files format
+
+the -config-file command line option specifies which file contains the
+configurations to run with.
+
+META: expand
+
+  %Apache::TestItSelf::Config = (
+      perl_exec     => '/home/stas/perl/5.8.5-ithread/bin/perl5.8.5',
+      mp_gen        => '2.0',
+      httpd_gen     => '2.0',
+      httpd_version => 'Apache/2.0.53-dev',
+      timeout       => 200,
+      makepl_arg    => 'MOD_PERL=2 -libmodperl mod_perl-5.8.5-ithread.so',
+  );
+  
+  my $path = '/home/stas/httpd';
+  
+  @Apache::TestItSelf::Configs = (
+      {
+       apxs_exec     => "$path/prefork/bin/apxs",
+       httpd_exec    => "$path/prefork/bin/httpd",
+       httpd_mpm     => "prefork",
+       test_verbose  => 0,
+      },
+      {
+       apxs_exec     => "$path/worker/bin/apxs",
+       httpd_exec    => "$path/worker/bin/httpd",
+       httpd_mpm     => "worker",
+       test_verbose  => 1,
+      },
+  );
+  1;
+
+
+=cut
+

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache2_modules_testitself_config.pm
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache2_modules_testitself_config.pm?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache2_modules_testitself_config.pm
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,24 @@
+%Apache::TestItSelf::Config = (
+    perl_exec     => '/home/stas/perl/5.8.5-ithread/bin/perl5.8.5',
+    mp_gen        => '2.0',
+    httpd_gen     => '2.0',
+    httpd_version => 'Apache/2.0.53-dev',
+    timeout       => 200,
+    test_verbose  => 0,
+);
+
+my $path = '/home/stas/httpd';
+
+@Apache::TestItSelf::Configs = ();
+for (qw(prefork worker)) {
+    push @Apache::TestItSelf::Configs,
+        {
+         apxs_exec     => "$path/$_/bin/apxs",
+         httpd_exec    => "$path/$_/bin/httpd",
+         httpd_conf    => "$path/$_/conf/httpd.conf",
+         httpd_mpm     => "$_",
+         makepl_arg    => "MOD_PERL=2 -libmodperl $path/$_/modules/mod_perl-5.8.5-ithread.so",
+        };
+}
+
+1;

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache_test_config.pm
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache_test_config.pm?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/apache_test_config.pm
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,24 @@
+%Apache::TestItSelf::Config = (
+    perl_exec     => '/home/stas/perl/5.8.5-ithread/bin/perl5.8.5',
+    mp_gen        => '2.0',
+    httpd_gen     => '2.0',
+    httpd_version => 'Apache/2.0.53-dev',
+    timeout       => 200,
+    test_verbose  => 0,
+);
+
+my $path = '/home/stas/httpd';
+
+@Apache::TestItSelf::Configs = ();
+for (qw(prefork worker)) {
+    push @Apache::TestItSelf::Configs,
+        {
+         apxs_exec     => "$path/$_/bin/apxs",
+         httpd_exec    => "$path/$_/bin/httpd",
+         httpd_conf    => "$path/$_/conf/httpd.conf",
+         httpd_mpm     => "$_",
+         makepl_arg    => "MOD_PERL=2 -libmodperl $path/$_/modules/mod_perl-5.8.5-ithread.so",
+        };
+}
+
+1;

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/modperl2_testitself_config.pm
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/modperl2_testitself_config.pm?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/sample/modperl2_testitself_config.pm
Sun Dec 19 20:06:54 2004
@@ -0,0 +1,26 @@
+%Apache::TestItSelf::Config = (
+    perl_exec     => '/home/stas/perl/5.8.5-ithread/bin/perl5.8.5',
+    mp_gen        => '2.0',
+    httpd_gen     => '2.0',
+    httpd_version => 'Apache/2.0.53-dev',
+    timeout       => 900, # make test may take a long time
+    makepl_arg    => '-libmodperl mod_perl-5.8.5-ithread.so',
+    test_verbose  => 0,
+);
+
+my $path = '/home/stas/httpd';
+my $common_makepl_arg = "MP_INST_APACHE2=1 MP_MAINTAINER=1";
+
+@Apache::TestItSelf::Configs = ();
+for (qw(prefork worker)) {
+    push @Apache::TestItSelf::Configs,
+        {
+         apxs_exec     => "$path/$_/bin/apxs",
+         httpd_exec    => "$path/$_/bin/httpd",
+         httpd_conf    => "$path/$_/conf/httpd.conf",
+         httpd_mpm     => "$_",
+         makepl_arg    => "MP_APXS=$path/$_/bin/apxs $common_makepl_arg",
+        };
+}
+
+1;

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/TEST.PL
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/TEST.PL?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/TEST.PL	Sun Dec 19 20:06:54
2004
@@ -0,0 +1,123 @@
+use strict;
+
+use lib qw(../../lib ../lib ./lib);
+
+use strict;
+use warnings FATAL => 'all';
+
+use Test::Harness;
+use FindBin;
+use File::Spec::Functions qw(catdir);
+use Apache::TestTrace;
+use Cwd qw(cwd);
+
+use Getopt::Long qw(GetOptions);
+
+my %usage = (
+   'base-dir'     => 'which dir to run the tests in (default: Apache-TestMe)',
+   'config-file'  => 'which config file to use',
+   'help'         => 'display this message',
+   'trace=T'      => 'change tracing default to: warning, notice, ' .
+                        'info, debug, ...',
+   'verbose[=1]'  => 'verbose output',
+);
+
+my @flag_opts    = qw(verbose help);
+my @string_opts  = qw(config-file base-dir trace);
+
+my %opts;
+# grab from @ARGV only the options that we expect
+GetOptions(\%opts, @flag_opts, (map "$_=s", @string_opts));
+
+# t/TEST -v -base /home/stas/apache.org/Apache-Test \
+# -config /home/stas/.apache-test/apache_test_config.pm
+#
+
+$Test::Harness::verbose = 1 if $opts{verbose};
+
+opt_help() if $opts{help};
+opt_help() unless $opts{'config-file'};
+
+if ($opts{'base-dir'}) {
+    unless (-d $opts{'base-dir'}) {
+        error "can't find $opts{'base-dir'}";
+        opt_help();
+    }
+}
+else {
+    my $dir = catdir $FindBin::Bin, qw(.. Apache-TestMe);
+    # get rid of relative paths
+    die "can't find the default dir $dir" unless -d $dir;
+    my $from = cwd();
+    chdir $dir or die "can't chdir to $dir: $!";
+    $dir = cwd();
+    chdir $from or die "can't chdir to $from: $!";
+    $opts{'base-dir'} = $dir;
+}
+
+
+unless (-r $opts{'config-file'}) {
+    error "can't read $opts{'config-file'}";
+    opt_help();
+}
+
+    if ($opts{trace}) {
+        my %levels = map {$_ => 1} @Apache::TestTrace::Levels;
+        if (exists $levels{ $opts{trace} }) {
+            $Apache::TestTrace::Level = $opts{trace};
+            # propogate the override for the server-side.
+            # -trace overrides any previous APACHE_TEST_TRACE_LEVEL settings
+            $ENV{APACHE_TEST_TRACE_LEVEL} = $opts{trace};
+        }
+        else {
+            error "unknown trace level: $opts{trace}",
+                "valid levels are: @Apache::TestTrace::Levels";
+            opt_help();
+        }
+    }
+
+# forward the data to the sub-processes run by Test::Harness
+$ENV{APACHE_TESTITSELF_CONFIG_FILE} = $opts{'config-file'};
+$ENV{APACHE_TESTITSELF_BASE_DIR}    = $opts{'base-dir'};
+
+run_my_tests();
+
+sub run_my_tests {
+
+    my $base = "t";
+    unless (-d $base) {
+        # try to move into the top-level directory
+        chdir ".." or die "Can't chdir: $!";
+    }
+
+    my @tests;
+    if (@ARGV) {
+        for (@ARGV) {
+            if (-d $_) {
+                push @tests, <$_/*.t>;
+            } else {
+                $_ .= ".t" unless /\.t$/;
+                push @tests, $_;
+            }
+        }
+    } else {
+        chdir $base;
+        @tests = sort (<*.t>);
+        chdir "..";
+        @tests = map { "$base/$_" } @tests;
+    }
+
+    runtests @tests;
+}
+
+sub opt_help {
+    print <<EOM;
+usage: TEST [options ...]
+   where options include:
+EOM
+
+    for (sort keys %usage){
+        printf "  -%-13s %s\n", $_, $usage{$_};
+    }
+    exit;
+}

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/httpd_arg.t
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/httpd_arg.t?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/httpd_arg.t	Sun Dec 19
20:06:54 2004
@@ -0,0 +1,118 @@
+#
+# basic testing with -httpd argument passed explicitly (to
+# Makefile.PL, to t/TEST, etc.)
+#
+
+# XXX: -apxs should be really the same test but passing -apxs instead
+# of -httpd, so consider to just run both in this test
+
+use strict;
+use warnings FATAL => 'all';
+
+use Test::More;
+use MyTest::Util qw(myrun3 go_in go_out test_configs);
+use Apache::TestConfig ();
+
+my @configs = test_configs();
+my $tests_per_config = 18;
+plan tests => $tests_per_config * @configs;
+
+my $orig_dir = go_in();
+
+for my $c (@configs) {
+    Apache::TestConfig::custom_config_nuke();
+    $ENV{APACHE_TEST_NO_STICKY_PREFERENCES} = 1;
+    makefile_pl_plus_httpd_arg($c);
+
+    # this one will have custom config, but it shouldn't interrupt
+    # with the explicit one
+    # XXX: useless at the moment, since the previously stored custom
+    # config and the explicit config both point to the same config
+    $ENV{APACHE_TEST_NO_STICKY_PREFERENCES} = 0;
+    makefile_pl_plus_httpd_arg($c);
+
+    Apache::TestConfig::custom_config_nuke();
+    t_TEST_plus_httpd_arg($c);
+}
+
+go_out($orig_dir);
+
+# 6 tests
+# explicit Makefile.PL -httpd argument
+sub makefile_pl_plus_httpd_arg {
+    my $c = shift;
+
+    my($cmd, $out, $err);
+
+    # clean and ignore the results
+    $cmd = "make clean";
+    ($out, $err) = myrun3($cmd);
+
+    my $makepl_arg = $c->{makepl_arg} || '';
+    $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg " .
+        "-httpd $c->{httpd_exec} -httpd_conf $c->{httpd_conf}";
+    ($out, $err) = myrun3($cmd);
+    unlike $err, qr/\[  error\]/, $cmd;
+
+    $cmd = "make";
+    ($out, $err) = myrun3($cmd);
+    is $err, "", $cmd;
+
+    my $test_verbose = $c->{test_verbose} ? "TEST_VERBOSE=1" : "";
+    $cmd = "make test $test_verbose";
+    ($out, $err) = myrun3($cmd);
+    like $out, qr/using $c->{httpd_version} \($c->{httpd_mpm} MPM\)/, $cmd;
+    like $out, qr/All tests successful/, $cmd;
+    unlike $err, qr/\[  error\]/, $cmd;
+
+    # test that httpd is found in t/REPORT (if exists)
+    SKIP: {
+        $cmd = "t/REPORT";
+        skip "$cmd doesn't exist", 1 unless -e $cmd;
+
+        ($out, $err) = myrun3($cmd);
+        like $out, qr/Server version: $c->{httpd_version}/, $cmd;
+    }
+}
+
+# explicit t/TEST -httpd argument
+sub t_TEST_plus_httpd_arg {
+    my $c = shift;
+
+    my($cmd, $out, $err);
+
+    # clean and ignore the results
+    $cmd = "make clean";
+    ($out, $err) = myrun3($cmd);
+
+    my $makepl_arg = $c->{makepl_arg} || '';
+    $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg";
+    ($out, $err) = myrun3($cmd);
+    unlike $err, qr/\[  error\]/, $cmd;
+
+    $cmd = "make";
+    ($out, $err) = myrun3($cmd);
+    is $err, "", $cmd;
+
+    my $test_verbose = $c->{test_verbose} ? "-v " : "";
+    $cmd = "t/TEST -httpd $c->{httpd_exec} $test_verbose";
+    ($out, $err) = myrun3($cmd);
+    like $out,
+        qr/using $c->{httpd_version} \($c->{httpd_mpm} MPM\)/,
+        $cmd;
+    like $out, qr/All tests successful/, $cmd;
+    unlike $err, qr/\[  error\]/, $cmd;
+
+    # test that httpd is found in t/REPORT (if exists)
+    $cmd = "t/REPORT";
+    if (-e $cmd) {
+        ($out, $err) = myrun3($cmd);
+        like $out, qr/Server version: $c->{httpd_version}/, $cmd;
+    }
+    else {
+        ok 1;
+    }
+}
+
+__END__
+

Added: httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/interactive.t
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/interactive.t?view=auto&rev=122807
==============================================================================
--- (empty file)
+++ httpd/test/trunk/perl-framework/Apache-Test/Apache-TestItSelf/t/interactive.t	Sun Dec
19 20:06:54 2004
@@ -0,0 +1,150 @@
+#
+# interactive testing (when A-T) can't figure out the configuration
+#
+
+use Test::More;
+
+use IPC::Run qw(start pump finish timeout);
+use Cwd qw(cwd);
+use File::Spec::Functions qw(catfile);
+
+use MyTest::Util qw(myrun3 go_in go_out work_dir check_eval
+                    test_configs);
+
+use Apache::TestConfig ();
+use Apache::TestTrace;
+
+# in this test we don't want any cached preconfiguration to kick in
+# A-T is aware of this env var and won't load neither custom config, nor
+# Apache/Build.pm from mod_perl2.
+local $ENV{APACHE_TEST_INTERACTIVE_CONFIG_TEST} = 1;
+
+my @configs = test_configs();
+my $tests_per_config = 11;
+plan tests => $tests_per_config * @configs + 1;
+
+my $orig_dir = go_in();
+
+my $cwd = cwd();
+my $expected_work_dir = work_dir();
+is $cwd, $expected_work_dir, "working in $expected_work_dir";
+
+debug "cwd: $cwd";
+
+for my $c (@configs) {
+
+    # install the sticky custom config
+    install($c);
+
+    # interactive config doesn't work with this var on
+    $ENV{APACHE_TEST_NO_STICKY_PREFERENCES} = 0;
+    basic($c);
+}
+
+go_out($orig_dir);
+
+# 4 tests
+sub install {
+    my $c = shift;
+
+    my($cmd, $out, $err);
+
+    $cmd = "make clean";
+    ($out, $err) = myrun3($cmd);
+    # ignore the results
+
+    my $makepl_arg = $c->{makepl_arg} || '';
+    $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg " .
+        "-httpd $c->{httpd_exec} -apxs $c->{apxs_exec}";
+    ($out, $err) = myrun3($cmd);
+    my $makefile = catfile $expected_work_dir, "Makefile";
+    is -e $makefile, 1, "generated $makefile";
+    unlike $err, qr/\[  error\]/, "checking for errors";
+
+    $cmd = "make";
+    ($out, $err) = myrun3($cmd);
+    is $err, "", $cmd;
+
+    $cmd = "make install";
+    ($out, $err) = myrun3($cmd);
+    unlike $err, qr/\[  error\]/, $cmd;
+}
+
+# 7 tests
+sub basic {
+    my $c = shift;
+
+    my($cmd, $out, $err);
+
+    # clean and ignore the results
+    $cmd = "make clean";
+    ($out, $err) = myrun3($cmd);
+
+    my $makepl_arg = $c->{makepl_arg} || '';
+    $cmd = "$c->{perl_exec} Makefile.PL $makepl_arg";
+    ($out, $err) = myrun3($cmd);
+    unlike $err, qr/\[  error\]/, $cmd;
+
+    $cmd = "make";
+    ($out, $err) = myrun3($cmd);
+    is $err, "", $cmd;
+
+    {
+        my $in;
+        my $expected = '';
+        my @cmd = qw(make test);
+        push @cmd, "TEST_VERBOSE=1" if $c->{test_verbose};
+        $cmd = join " ", @cmd;
+
+        # bypass the -t STDIN checks to still ensure the interactive
+        # config prompts
+        $ENV{APACHE_TEST_INTERACTIVE_PROMPT_OK} = 1;
+
+        $in  = '';
+        $out = '';
+        $err = '';
+        my $h = start \@cmd, \$in, \$out, \$err, timeout($c->{timeout});
+
+        # here the expect fails if the interactive config doesn't kick
+        # in, but for example somehow figures out the needed
+        # information (httpd/apxs) and runs the test suite normally
+        $expected = "Please provide a full path to 'httpd' executable";
+        eval { $h->pump until $out =~ /$expected/gc };
+        my $reset_std = 1;
+        check_eval($cmd, $out, $err, $reset_std,
+                   "interactive config wasn't invoked");
+
+        $in .= "$c->{httpd_exec}\n" ;
+        $expected = "Please provide a full path to .*? 'apxs' executable";
+        eval { $h->pump until $out =~ /$expected/gc };
+        $reset_std = 1;
+        check_eval($cmd, $out, $err, $reset_std,
+                   "interactive config had a problem");
+
+        $in .= "$c->{apxs_exec}\n" ;
+        eval { $h->finish };
+        $reset_std = 0; # needed for later sub-tests
+        check_eval($cmd, $out, $err, $reset_std,
+                   "failed to finish $cmd");
+        like $out, qr/using $c->{httpd_version} \($c->{httpd_mpm} MPM\)/,
+            "$cmd: using $c->{httpd_version} \($c->{httpd_mpm} MPM";
+        like $out, qr/All tests successful/, "$cmd: All tests successful";
+        unlike $err, qr/\[  error\]/, "$cmd: no error messages";
+    }
+
+    $cmd = "make install";
+    ($out, $err) = myrun3($cmd);
+    unlike $err, qr/\[  error\]/, $cmd;
+
+    # test that httpd is found in t/REPORT (if exists)
+    SKIP: {
+        $cmd = "t/REPORT";
+        skip "$cmd doesn't exist", 1 unless -e $cmd;
+
+        ($out, $err) = myrun3($cmd);
+        like $out, qr/Server version: $c->{httpd_version}/, $cmd;
+    }
+}
+
+__END__
+

Modified: httpd/test/trunk/perl-framework/Apache-Test/Changes
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Changes?view=diff&rev=122807&p1=httpd/test/trunk/perl-framework/Apache-Test/Changes&r1=122806&p2=httpd/test/trunk/perl-framework/Apache-Test/Changes&r2=122807
==============================================================================
--- httpd/test/trunk/perl-framework/Apache-Test/Changes	(original)
+++ httpd/test/trunk/perl-framework/Apache-Test/Changes	Sun Dec 19 20:06:54 2004
@@ -8,6 +8,8 @@
   
 =item 1.18-dev
 
+add Apache-TestItSelf and Apache-TestMe sub-projects. [Stas]
+
 add various straps to aid the new Apache-TestItSelf sub-project, which
 is used to test A-T config options [Stas]
 

Modified: httpd/test/trunk/perl-framework/Apache-Test/META.yml
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/META.yml?view=diff&rev=122807&p1=httpd/test/trunk/perl-framework/Apache-Test/META.yml&r1=122806&p2=httpd/test/trunk/perl-framework/Apache-Test/META.yml&r2=122807
==============================================================================
--- httpd/test/trunk/perl-framework/Apache-Test/META.yml	(original)
+++ httpd/test/trunk/perl-framework/Apache-Test/META.yml	Sun Dec 19 20:06:54 2004
@@ -12,6 +12,5 @@
     package:
         - HTTP::Request::Common
         - warnings
-
-
-
+    directory:
+        - Apache-TestItSelf

Modified: httpd/test/trunk/perl-framework/Apache-Test/Makefile.PL
Url: http://svn.apache.org/viewcvs/httpd/test/trunk/perl-framework/Apache-Test/Makefile.PL?view=diff&rev=122807&p1=httpd/test/trunk/perl-framework/Apache-Test/Makefile.PL&r1=122806&p2=httpd/test/trunk/perl-framework/Apache-Test/Makefile.PL&r2=122807
==============================================================================
--- httpd/test/trunk/perl-framework/Apache-Test/Makefile.PL	(original)
+++ httpd/test/trunk/perl-framework/Apache-Test/Makefile.PL	Sun Dec 19 20:06:54 2004
@@ -30,6 +30,7 @@
 my @scripts = qw(t/TEST);
 
 finddepth(sub {
+    return if $_ eq 'Apache-TestItSelf';
     return unless /(.*?\.pl)\.PL$/;
     push @scripts, "$File::Find::dir/$1";
 }, '.');

Mime
View raw message