You are viewing a plain text version of this content. The canonical link for it is here.
Posted to test-dev@httpd.apache.org by Randy Kobes <ra...@theoryx5.uwinnipeg.ca> on 2003/09/01 06:22:10 UTC

Re: need help to add per-user config to Apache::Test

[ trimmed mod_perl mailing list from cc ]

On Fri, 29 Aug 2003, Randy Kobes wrote:

> On Thu, 28 Aug 2003, Stas Bekman wrote:
>
> > Several people have asked for having a new feature in
> > Apache::Test: they want to configure it once (where the
> > server, apxs, etx are) and run Apache::Test without
> > needing to pass any arguments. Matt suggested that it
> > should remember the values passed the first time it's used
> > and then re-use them. However on a system with several
> > users and different preferences, this won't work.
> > Therefore we need to be able to support per-user
> > preferences. CPAN.pm's setup seems to provide a good
> > solution to the same problem (CPAN/Config.pm and
> > ~user/.cpan/CPAN/Config.pm). So I thought that someone
> > would like to port the functionality from CPAN.pm to
> > Apache::Test and send the patches here. It's all pure
> > perl, so you have no excuses that it's XS/C ;)
>
> I have a mostly functional version of this, save for
> the ability to use a $HOME/.apache-test/Config.pm, which
> shouldn't be too hard to add. I'll try to finish it
> off this weekend.

A stab at this follows ... It's rough, as I wanted to
make sure this was on the right track; basically, what's
supposed to happen is
- if a Apache::MyTestConfig is found, use the values for
apxs, httpd, user, group, and port stored in there. These
values get overridden if they appear as arguments to 'perl
Makefile.PL'.
- if no Apache::MyTestConfig is present, or a '-save'
option is passed to 'perl t/TEST', Apache::MyTestConfig
is created, and then installed.
- the location of Apache::MyTestConfig is, first of all,
under $HOME/.apache-test/, or if this is not present,
under the system @INC.

I'm not sure I'm putting the values of
Apache::MyTestConfig in the right, or best, place;
I haven't tested it extensively, as my linux box
is a live server.

=========================================================
Index: TestConfig.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfig.pm,v
retrieving revision 1.171
diff -u -r1.171 TestConfig.pm
--- TestConfig.pm	13 Aug 2003 19:02:51 -0000	1.171
+++ TestConfig.pm	1 Sep 2003 03:51:13 -0000
@@ -3,6 +3,22 @@
 use strict;
 use warnings FATAL => 'all';

+require File::Spec;
+sub has_config {
+    my $has_config = 0;
+    if ($ENV{HOME}) {
+        eval
+            {require File::Spec->catfile($ENV{HOME},
+                                         '.apache-test', 'MyTestConfig.pm');};
+        $has_config = 1 unless $@;
+    }
+    unless ($has_config) {
+        eval {require Apache::MyTestConfig;};
+        $has_config = 1 unless $@;
+    }
+    return $has_config;
+}
+
 use constant WIN32   => $^O eq 'MSWin32';
 use constant CYGWIN  => $^O eq 'cygwin';
 use constant NETWARE => $^O eq 'NetWare';
@@ -24,8 +40,8 @@
 use File::Path ();
 use File::Spec::Functions qw(catfile abs2rel splitdir canonpath
                              catdir file_name_is_absolute);
-use Cwd qw(fastcwd);

+use Cwd qw(fastcwd);
 use Apache::TestConfigPerl ();
 use Apache::TestConfigParse ();
 use Apache::TestTrace;
@@ -34,6 +50,8 @@

 use vars qw(%Usage);

+use constant HAS_CONFIG => has_config();
+
 %Usage = (
    top_dir       => 'top-level directory (default is $PWD)',
    t_dir         => 'the t/ test directory (default is $top_dir/t)',
@@ -72,6 +90,12 @@

 sub filter_args {
     my($args, $wanted_args) = @_;
+    if (HAS_CONFIG) {
+        for (qw(group user apxs port httpd)) {
+            next unless defined $Apache::MyTestConfig->{$_};
+            unshift @$args, "-$_", $Apache::MyTestConfig->{$_};
+        }
+    }
     my(@pass, %keep);

     my @filter = @$args;
Index: TestRun.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestRun.pm,v
retrieving revision 1.113
diff -u -r1.113 TestRun.pm
--- TestRun.pm	22 Jul 2003 11:21:36 -0000	1.113
+++ TestRun.pm	1 Sep 2003 03:51:14 -0000
@@ -11,10 +11,14 @@
 use Apache::TestHarness ();
 use Apache::TestTrace;

+use constant HAS_CONFIG => Apache::TestConfig::HAS_CONFIG;
+
 use File::Find qw(finddepth);
-use File::Spec::Functions qw(catfile);
+use File::Spec::Functions qw(catfile catdir);
 use Getopt::Long qw(GetOptions);
+use File::Basename;
 use Config;
+use Symbol qw(gensym);

 use constant STARTUP_TIMEOUT => 300; # secs (good for extreme debug cases)
 use subs qw(exit_shell exit_perl);
@@ -23,7 +27,7 @@
 my %original_t_perms = ();

 my @std_run      = qw(start-httpd run-tests stop-httpd);
-my @others       = qw(verbose configure clean help ssl http11);
+my @others       = qw(verbose configure clean help ssl http11 save);
 my @flag_opts    = (@std_run, @others);
 my @string_opts  = qw(order trace);
 my @ostring_opts = qw(proxy ping);
@@ -55,6 +59,7 @@
    'ssl'             => 'run tests through ssl',
    'proxy'           => 'proxy requests (default proxy is localhost)',
    'trace=T'         => 'change tracing default to: warning, notice, info, debug, ...',
+   'save'            => 'save test paramaters into Apache::MyTestConfig',
    (map { $_, "\U$_\E url" } @request_opts),
 );

@@ -614,6 +619,10 @@
     $self->run_tests;

     $self->stop;
+
+    $self->write_config() if
+        ($self->{opts}->{save} || not HAS_CONFIG);
+
 }

 my @oh = qw(jeez golly gosh darn shucks dangit rats nuts dangnabit crap);
@@ -915,6 +924,75 @@
 #    require Carp;
 #    Carp::cluck('exiting');
     CORE::exit $_[0];
+}
+
+sub write_config {
+    my $self = shift;
+    my $dir;
+    for (@INC) {
+        my $candidate = catfile($_, 'Apache', 'Test.pm');
+        if (-e $candidate) {
+            $dir = dirname($candidate);
+            last;
+        }
+    }
+    unless (-w $dir) {
+        $dir = catdir($ENV{HOME}, '.apache-test');
+        unless (-d $dir) {
+            mkdir $dir or do {
+                warn "Cannot mkdir $dir: $!";
+                return;
+            };
+        }
+    }
+
+    my $fh = Symbol::gensym();
+    my $file = catfile($dir, 'MyTestConfig.pm');
+    unless (open($fh, ">$file")) {
+        warn "Cannot open $file: $!";
+        return;
+    }
+    warn "Writing $file ....\n";
+    my $vars = $self->{test_config}->{vars};
+    my $config_dump;
+    for (qw(group user apxs port httpd)) {
+        next unless $vars->{$_};
+        $config_dump .= qq{    '$_' => } . qq{'$vars->{$_}',\n};
+    }
+
+    my $pkg = << "EOC";
+package Apache::MyTestConfig;
+\$Apache::MyTestConfig = {
+$config_dump
+};
+1;
+
+=head1 NAME
+
+Apache::MyTestConfig - Configuration file for Apache::Test
+
+=cut
+EOC
+    print $fh $pkg;
+    close $fh;
+    my $test = catdir($vars->{top_dir}, 'blib/lib/Apache');
+    if (-e catfile($test, 'Test.pm')) {
+        my $fh = Symbol::gensym();
+        my $file = catfile($test, 'MyTestConfig.pm');
+        if (-e $file) {
+            unlink $file or do {
+                warn "Cannot unlink $file: $!";
+                return;
+            }
+        }
+        unless (open($fh, ">$file")) {
+            warn "Cannot open $file: $!";
+            return;
+        }
+        print $fh $pkg;
+        close $fh;
+    }
+    return 1;
 }

 1;
===================================================================

-- 
best regards,
randy

Re: need help to add per-user config to Apache::Test

Posted by Stas Bekman <st...@stason.org>.
Randy Kobes wrote:

>>>>In the effort to remove some of the Win32 noise, I was
>>>>thinking that we can write a generic function which gets a
>>>>path as an argument and figures out internally if it needs
>>>>to keep the argument as passed or mangle it. So it'll do
>>>>something like:
>>>>
>>>>    my $cwd =  Apache::TestUtil::path(cwd);
>>>>
>>>>probably need a more intuitive name for this function.
>>>
>>>
>>>That'd be nice - a version that does this appears below.
>>>I named it win32_long_path - it'll just return what was
>>>passed into it if not on Win32.
>>
>>But my idea was to eliminate any os-specific words win32. I think it should
>>just be long_path... Think of it as File::Spec function.
> 
> 
> OK, I'll do that. I put in the win32_ to indicate that it'll
> do something for Win32, and otherwise just return what was
> passed in.
> 
> 
>>I'm still not quite happy about the naming of the function, what exactly
>>GetLongPathName($file) does?
>>can this be done using some File::Spec function?
> 
> 
> I haven't found an equivalent one in File::Spec ... The
> problem here is that cwd (or any file/directory name) on
> Win32 has two representations - a long path name (that can
> include spaces) and a short path name, limited to 6
> characters (this is a holdout from early days), plus 3 if an
> extension is present.  Here we want to match cwd to
> /Apache-Test/, but cwd may return the short path name (eg,
> Apache~1.0), depending on if, for example, you have
> different Apache-Test* directories at the same level. So
> GetLongPathName can be used to get the full long path name.
> 
> The thing with naming it, eg, just long_path, is that
> Unix users (the majority) wouldn't know what it does.

Thanks Randy. Call it 'expand_path' and add the above explanation to that 
function? for unix it won't do anything, since there is nothing to expand, but 
for win32 it will expand the shrinkwrapped name.

>>>+        if (-e $candidate) {
>>>+            $sys_config = $candidate;
>>>+            last;
>>>+        }
>>>+    }
>>>+    if ($sys_config) {
>>>+        eval {require $sys_config};
>>>+        return $sys_config if (not $@ and IN_APACHE_TEST);
>>>+        $sys_config = undef if $@;
>>>+    }
>>
>>Hmm, I thought we agreed that eval {require $sys_config} will always succeed,
>>since that file is always available. so this code should be needed:
>>
>>+ die 'Could not find a suitable Apache::TestConfigData'
>>+    unless defined CONFIG_DATA;
> 
> 
> I was thinking here if someone, after installation, had
> mis-edited Apache::TestConfigData, either the system one or
> one found in some path in @INC being added thru, eg, use
> lib). But this might be overkill - not worrying about this
> at this time will simplify things here.

Yup, just die then...

> I was also thinking about the problem of $ENV{HOME} not
> being available in mod_perl. As Apache::TestConfigData is
> being loaded in order to configure things, shouldn't
> this not be a problem, because at this point one isn't
> yet in a mod_perl environment?

It can be used at run time just as well, I think we do that in several places 
in the test suite. However for now we can cheat, by documenting:

   add:

     PerlPassEnv HOME

   to httpd.conf if you want to read ~/.apache-test/ config from within a 
running mod_perl server. Another possible alternative is to use: getpwent() to 
ask the os for the home dir instead of relying on $ENV{HOME}. Does this work 
under win32?



__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: need help to add per-user config to Apache::Test

Posted by Randy Kobes <ra...@theoryx5.uwinnipeg.ca>.
On Sat, 6 Sep 2003, Stas Bekman wrote:

> Randy Kobes wrote:
> > On Thu, 4 Sep 2003, Stas Bekman wrote:
> >
> >
> >>In the effort to remove some of the Win32 noise, I was
> >>thinking that we can write a generic function which gets a
> >>path as an argument and figures out internally if it needs
> >>to keep the argument as passed or mangle it. So it'll do
> >>something like:
> >>
> >>     my $cwd =  Apache::TestUtil::path(cwd);
> >>
> >>probably need a more intuitive name for this function.
> >
> >
> > That'd be nice - a version that does this appears below.
> > I named it win32_long_path - it'll just return what was
> > passed into it if not on Win32.
>
> But my idea was to eliminate any os-specific words win32. I think it should
> just be long_path... Think of it as File::Spec function.

OK, I'll do that. I put in the win32_ to indicate that it'll
do something for Win32, and otherwise just return what was
passed in.

> I'm still not quite happy about the naming of the function, what exactly
> GetLongPathName($file) does?
> can this be done using some File::Spec function?

I haven't found an equivalent one in File::Spec ... The
problem here is that cwd (or any file/directory name) on
Win32 has two representations - a long path name (that can
include spaces) and a short path name, limited to 6
characters (this is a holdout from early days), plus 3 if an
extension is present.  Here we want to match cwd to
/Apache-Test/, but cwd may return the short path name (eg,
Apache~1.0), depending on if, for example, you have
different Apache-Test* directories at the same level. So
GetLongPathName can be used to get the full long path name.

The thing with naming it, eg, just long_path, is that
Unix users (the majority) wouldn't know what it does.

> > +require File::Spec;
>
> > +        my $candidate = File::Spec->catfile($_, 'Apache', $file);
>
> we import catfile in all other Apache::Test files, can do
> that here as well...  will make code simpler

Good point - thanks.

>
> > +        if (-e $candidate) {
> > +            $sys_config = $candidate;
> > +            last;
> > +        }
> > +    }
> > +    if ($sys_config) {
> > +        eval {require $sys_config};
> > +        return $sys_config if (not $@ and IN_APACHE_TEST);
> > +        $sys_config = undef if $@;
> > +    }
>
> Hmm, I thought we agreed that eval {require $sys_config} will always succeed,
> since that file is always available. so this code should be needed:
>
> + die 'Could not find a suitable Apache::TestConfigData'
> +    unless defined CONFIG_DATA;

I was thinking here if someone, after installation, had
mis-edited Apache::TestConfigData, either the system one or
one found in some path in @INC being added thru, eg, use
lib). But this might be overkill - not worrying about this
at this time will simplify things here.

> One more problem is TestRun.pm's layout: subs should go
> after the declarations (uses/constants/etc). use 'use
> subs' if you need to predeclare them.

OK - thanks.

> Another issue, is in_apache_test. Since a user may get it
> with modperl-2.0 or separately it should return true in
> either case.

I forgot about that - thanks.

> > +sub write_config {
> > +    my $self = shift;
> > +    my $fh = Symbol::gensym();
> > +    my $vars = $self->{test_config}->{vars};
> > +    my $conf_opts = $self->{conf_opts};
> > +    my $file = IN_APACHE_TEST ?
> > +        catfile($vars->{top_dir}, CONFIG_DATA) :
> > +        CONFIG_DATA;
>
> it's easier to parse when written as:
>
> my $file = IN_APACHE_TEST
>      ? catfile($vars->{top_dir}, CONFIG_DATA)
>      : CONFIG_DATA;
>
> > +    my $pkg = << "EOC";
> > +package Apache::TestConfigData;
>
> better have it strict, to avoid misterious errors (same in the pod below)
>
> use strict;
> use warnings;
>
> use vars (\$Apache::TestConfigData);

Thanks - I'll add that.

I was also thinking about the problem of $ENV{HOME} not
being available in mod_perl. As Apache::TestConfigData is
being loaded in order to configure things, shouldn't
this not be a problem, because at this point one isn't
yet in a mod_perl environment?

-- 
best regards,
randy

Re: need help to add per-user config to Apache::Test

Posted by Stas Bekman <st...@stason.org>.
Randy Kobes wrote:
> On Thu, 4 Sep 2003, Stas Bekman wrote:
> 
> 
>>In the effort to remove some of the Win32 noise, I was
>>thinking that we can write a generic function which gets a
>>path as an argument and figures out internally if it needs
>>to keep the argument as passed or mangle it. So it'll do
>>something like:
>>
>>     my $cwd =  Apache::TestUtil::path(cwd);
>>
>>probably need a more intuitive name for this function.
> 
> 
> That'd be nice - a version that does this appears below.
> I named it win32_long_path - it'll just return what was
> passed into it if not on Win32.

But my idea was to eliminate any os-specific words win32. I think it should 
just be long_path... Think of it as File::Spec function.

I'm still not quite happy about the naming of the function, what exactly 
GetLongPathName($file) does?
can this be done using some File::Spec function?

> +require File::Spec;

> +        my $candidate = File::Spec->catfile($_, 'Apache', $file);

we import catfile in all other Apache::Test files, can do that here as well... 
will make code simpler

> +        if (-e $candidate) {
> +            $sys_config = $candidate;
> +            last;
> +        }
> +    }
> +    if ($sys_config) {
> +        eval {require $sys_config};
> +        return $sys_config if (not $@ and IN_APACHE_TEST);
> +        $sys_config = undef if $@;
> +    }

Hmm, I thought we agreed that eval {require $sys_config} will always succeed, 
since that file is always available. so this code should be needed:

+ die 'Could not find a suitable Apache::TestConfigData'
+    unless defined CONFIG_DATA;

One more problem is TestRun.pm's layout: subs should go after the declarations 
(uses/constants/etc). use 'use subs' if you need to predeclare them.

Another issue, is in_apache_test. Since a user may get it with modperl-2.0 or 
separately it should return true in either case.

> +sub write_config {
> +    my $self = shift;
> +    my $fh = Symbol::gensym();
> +    my $vars = $self->{test_config}->{vars};
> +    my $conf_opts = $self->{conf_opts};
> +    my $file = IN_APACHE_TEST ?
> +        catfile($vars->{top_dir}, CONFIG_DATA) :
> +        CONFIG_DATA;

it's easier to parse when written as:

my $file = IN_APACHE_TEST
     ? catfile($vars->{top_dir}, CONFIG_DATA)
     : CONFIG_DATA;

> +    my $pkg = << "EOC";
> +package Apache::TestConfigData;

better have it strict, to avoid misterious errors (same in the pod below)

use strict;
use warnings;

use vars (\$Apache::TestConfigData);

> +\$Apache::TestConfigData = {
> +$config_dump
> +};
> +1;
> +
> +=head1 NAME
> +
> +Apache::TestConfigData - Configuration file for Apache::Test
> +
> +=cut
> +EOC
> +    print $fh $pkg;
> +    close $fh;
> +    return 1;
> +}
> +
>  1;



__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: need help to add per-user config to Apache::Test

Posted by Randy Kobes <ra...@theoryx5.uwinnipeg.ca>.
On Thu, 4 Sep 2003, Stas Bekman wrote:

> In the effort to remove some of the Win32 noise, I was
> thinking that we can write a generic function which gets a
> path as an argument and figures out internally if it needs
> to keep the argument as passed or mangle it. So it'll do
> something like:
>
>      my $cwd =  Apache::TestUtil::path(cwd);
>
> probably need a more intuitive name for this function.

That'd be nice - a version that does this appears below.
I named it win32_long_path - it'll just return what was
passed into it if not on Win32.

[ .. ]
> Just a sanity check, the env var overrides (.e.g. USER)
> come in later, right?

I checked that the environment variables Apache::Test
recognizes do override the settings in
Apache::TestConfigData, if they are set, and will be saved
to Apache::TestConfigData if -save is passed to t/TEST.

I think I got the indentation right this time. Also,
I've added in a bit of pod to describe this.

==============================================================
Index: TestRun.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestRun.pm,v
retrieving revision 1.113
diff -u -r1.113 TestRun.pm
--- TestRun.pm	22 Jul 2003 11:21:36 -0000	1.113
+++ TestRun.pm	6 Sep 2003 15:40:09 -0000
@@ -10,20 +10,67 @@
 use Apache::TestRequest ();
 use Apache::TestHarness ();
 use Apache::TestTrace;
+use Apache::TestUtil qw(win32_long_path);
+
+use Cwd;
+# Are we building things within Apache-Test?
+sub in_apache_test {
+    my $cwd =  win32_long_path(cwd);
+    return ($cwd =~ m{Apache-Test}) ? 1 : 0;
+}
+use constant IN_APACHE_TEST => in_apache_test();
+
+require File::Spec;
+# routine to determine where the configuration file
+# Apache::TestConfigData lives. The order searched is
+# 1) a path within Apache-Test, if we are building things there
+# 2) an $ENV{HOME}/.apache-test/ directory;
+# 3) somewhere in @INC, other than a path within Apache-Test.
+sub config_data {
+    my $sys_config;
+    my $file = 'TestConfigData.pm';
+    for (@INC) {
+        my $candidate = File::Spec->catfile($_, 'Apache', $file);
+        if (-e $candidate) {
+            $sys_config = $candidate;
+            last;
+        }
+    }
+    if ($sys_config) {
+        eval {require $sys_config};
+        return $sys_config if (not $@ and IN_APACHE_TEST);
+        $sys_config = undef if $@;
+    }
+    # XXX $ENV{HOME} isn't propagated in mod_perl
+    if ($ENV{HOME}) {
+        my $priv_config = File::Spec->catfile($ENV{HOME},
+                                              '.apache-test',
+                                              $file);
+        eval {require $priv_config};
+        return $priv_config unless $@;
+    }
+    return $sys_config ? $sys_config : undef;
+}
+
+use constant CONFIG_DATA => config_data();

 use File::Find qw(finddepth);
-use File::Spec::Functions qw(catfile);
+use File::Spec::Functions qw(catfile catdir);
 use Getopt::Long qw(GetOptions);
+use File::Basename qw(dirname);
 use Config;

 use constant STARTUP_TIMEOUT => 300; # secs (good for extreme debug cases)
 use subs qw(exit_shell exit_perl);

+die 'Could not find a suitable Apache::TestConfigData'
+    unless defined CONFIG_DATA;
+
 my %core_files  = ();
 my %original_t_perms = ();

 my @std_run      = qw(start-httpd run-tests stop-httpd);
-my @others       = qw(verbose configure clean help ssl http11);
+my @others       = qw(verbose configure clean help ssl http11 save);
 my @flag_opts    = (@std_run, @others);
 my @string_opts  = qw(order trace);
 my @ostring_opts = qw(proxy ping);
@@ -55,6 +102,7 @@
    'ssl'             => 'run tests through ssl',
    'proxy'           => 'proxy requests (default proxy is localhost)',
    'trace=T'         => 'change tracing default to: warning, notice, info, debug, ...',
+   'save'            => 'save test paramaters into Apache::TestConfigData',
    (map { $_, "\U$_\E url" } @request_opts),
 );

@@ -407,6 +455,8 @@
     $test_config->cmodules_configure;
     $test_config->generate_httpd_conf;
     $test_config->save;
+    $self->write_config() if
+        (not %{$Apache::TestConfigData} or $self->{opts}->{save});
 }

 sub try_exit_opts {
@@ -509,6 +559,10 @@

 sub new_test_config {
     my $self = shift;
+    for (qw(httpd port user group apxs)) {
+        next unless $Apache::TestConfigData->{$_};
+        $self->{conf_opts}->{$_} ||= $Apache::TestConfigData->{$_};
+    }
     Apache::TestConfig->new($self->{conf_opts});
 }

@@ -917,6 +971,41 @@
     CORE::exit $_[0];
 }

+sub write_config {
+    my $self = shift;
+    my $fh = Symbol::gensym();
+    my $vars = $self->{test_config}->{vars};
+    my $conf_opts = $self->{conf_opts};
+    my $file = IN_APACHE_TEST ?
+        catfile($vars->{top_dir}, CONFIG_DATA) :
+        CONFIG_DATA;
+    die "Cannot open $file: $!" unless (open($fh, ">$file"));
+    warn "Writing $file.\n";
+    my $config_dump = '';
+    if ($self->{test_config}->{vars}->{httpd}) {
+        for (qw(group user apxs port httpd)) {
+            next unless my $var = $conf_opts->{$_} || $vars->{$_};
+            $config_dump .= qq{    '$_' => } . qq{'$var',\n};
+        }
+    }
+    my $pkg = << "EOC";
+package Apache::TestConfigData;
+\$Apache::TestConfigData = {
+$config_dump
+};
+1;
+
+=head1 NAME
+
+Apache::TestConfigData - Configuration file for Apache::Test
+
+=cut
+EOC
+    print $fh $pkg;
+    close $fh;
+    return 1;
+}
+
 1;

 __END__
@@ -963,5 +1052,37 @@

 Notice that the extension is I<.c>, and not I<.so>.

+=head1 Saving options
+
+When C<Apache::Test> is first installed, it will save the
+values of C<httpd>, C<port>, C<apxs>, C<user>, and C<group>,
+if set, to a configuration file C<Apache::TestConfigData>.
+This information will then be used in setting these options
+for subsequent uses.
+
+The values stored in C<Apache::TestConfigData> can be overriden
+temporarily either by setting the appropriate environment
+variable or by giving the relevant option when the C<TEST>
+script is run. If you want to save these options to
+C<Apache::TestConfigData>, use the C<-save> flag when
+running C<TEST>.
+
+If you are running C<Apache::Test> as a
+user who does not have permission to alter the system
+C<Apache::TestConfigData>, you can place your
+own private configuration file under C<$ENV{HOME}/.apache-test/>,
+which C<Apache::Test> will use, if present. An example
+of such a configuration file is
+
+  # file $ENV{HOME}/.apache-test/TestConfigData.pm
+  package Apache::TestConfigData;
+  $Apache::TestConfigData = {
+      'group' => 'me',
+      'user' => 'myself',
+      'port' => '8529',
+      'httpd' => '/usr/local/apache/bin/httpd',
+
+  };
+  1;

 =cut
Index: TestUtil.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestUtil.pm,v
retrieving revision 1.31
diff -u -r1.31 TestUtil.pm
--- TestUtil.pm	29 Apr 2003 08:04:04 -0000	1.31
+++ TestUtil.pm	6 Sep 2003 15:40:09 -0000
@@ -14,6 +14,8 @@

 use Apache::Test ();
 use Apache::TestConfig ();
+use constant WIN32 => Apache::TestConfig::WIN32;
+require Win32 if WIN32;

 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %CLEAN);

@@ -26,7 +28,8 @@
     t_client_log_error_is_expected t_client_log_warn_is_expected
 );

-@EXPORT_OK = qw(t_write_perl_script t_write_shell_script t_chown);
+@EXPORT_OK = qw(t_write_perl_script t_write_shell_script t_chown
+    win32_long_path win32_short_path);

 %CLEAN = ();

@@ -302,6 +305,18 @@
         t_debug("removing dir tree: $_");
         t_rmtree($_);
     }
+}
+
+# on Win32, returns the long path name, otherwise, does nothing
+sub win32_long_path {
+    my $file = shift;
+    return WIN32 ? Win32::GetLongPathName($file) : $file;
+}
+
+# on Win32, returns the short path name, otherwise, does nothing
+sub win32_short_path {
+    my $file = shift;
+    return WIN32 ? Win32::GetShortPathName($file) : $file;
 }

 1;
===================================================================

-- 
best regards,
randy

Re: need help to add per-user config to Apache::Test

Posted by Stas Bekman <st...@stason.org>.
Randy Kobes wrote:
> On Wed, 3 Sep 2003, Stas Bekman wrote:
> 
> 
>>Randy Kobes wrote:
>>
>>>On Tue, 2 Sep 2003, Stas Bekman wrote:
> 
> [ .. ]
> 
>>It should work during 'make test' as well, since it already runs t/TEST
>>-config. And also whenever you provide any options to t/TEST it reconfigures,
>>so I believe the normal run will do the same:
>>
>>  t/TEST -save -httpd /usr/local/httpd/bin/httpd
>>
>>I haven't tested that though.
> 
> 
> I've checked that (with the diff below), and it seems to
> work now as you say, both within Apache-Test and for a 3rd
> party package. Without the -save the new -httpd is used,
> but not saved into Apache::TestConfigData.
> [ .. ]

Great!

>>>Good idea - that's much simpler. The following assumes
>>>that an empty Apache/TestConfigData.pm is present, and
>>>then, as you say, 'make install' will pick up any changes
>>>that have been made to it.
>>
>>If I remember correctly 'make install' will complain about
>>the mismatch in sizes since 'make' has already put the
>>files into blib? Did it work for you just fine? Purhaps we
>>do need to update the two.
> 
> 
> On linux, I tried installing Apache-Test, and then changing
> the settings via
>    t/TEST -save -httpd /path/to/some/other/httpd
> This wrote a new lib/Apache/TestConfigData.pm, and
>    make install
> did recognize the change, copied it over to blib/, and
> installed the new copy.

Very good!

> The diff below also includes a change to better get the
> location of Apache::TestConfigData.
> ==============================================================
> Index: lib/Apache/TestRun.pm
> ===================================================================
> RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestRun.pm,v
> retrieving revision 1.113
> diff -u -r1.113 TestRun.pm
> --- lib/Apache/TestRun.pm	22 Jul 2003 11:21:36 -0000	1.113
> +++ lib/Apache/TestRun.pm	4 Sep 2003 21:02:44 -0000
> @@ -11,19 +11,69 @@
>  use Apache::TestHarness ();
>  use Apache::TestTrace;
> 
> +use constant WIN32 => Apache::TestConfig::WIN32;
> +require Win32 if WIN32;
> +
> +use Cwd;
> +# Are we building things within Apache-Test?
> +sub in_apache_test {
> +    my $cwd =  WIN32 ? Win32::GetLongPathName(cwd) : cwd;
> +    return ($cwd =~ m{Apache-Test}) ? 1 : 0;
> +}

In the effort to remove some of the Win32 noise, I was thinking that we can 
write a generic function which gets a path as an argument and figures out 
internally if it needs to keep the argument as passed or mangle it. So it'll 
do something like:

     my $cwd =  Apache::TestUtil::path(cwd);

probably need a more intuitive name for this function.

I suppose we can do it after this patch goes in, so that we don't mix too many 
changes at once. Unless you want to provide that function first and then 
adjust the patch to use it. It's up to you, either way is fine.

> +use constant IN_APACHE_TEST => in_apache_test();
> +
> +require File::Spec;
> +# routine to determine where the configuration file
> +# Apache::TestConfigData lives. The order searched is
> +# 1) a path within Apache-Test, if we are building things there
> +# 2) an $ENV{HOME}/.apache-test/ directory;
> +# 3) somewhere in @INC, other than a path within Apache-Test.
> +sub config_data {
> +    my $sys_config;
> +    my $file = 'TestConfigData.pm';
> +    for (@INC) {
> +	my $candidate = File::Spec->catfile($_, 'Apache', $file);
> +	if (-e $candidate) {
> +	    $sys_config = $candidate;
> +	    last;
> +	}
> +    }
> +    if ($sys_config) {
> +	eval {require $sys_config};
> +	return $sys_config if (not $@ and IN_APACHE_TEST);
> +	$sys_config = undef if $@;
> +    }
> +    # XXX $ENV{HOME} isn't propagated in mod_perl
> +    if ($ENV{HOME}) {
> +	my $priv_config = File::Spec->catfile($ENV{HOME},
> +					      '.apache-test',
> +					      $file);
> +        eval {require $priv_config};
> +	return $priv_config unless $@;
> +    }
> +    return $sys_config ? $sys_config : undef;
> +}

all the above needs proper indentation (4).

> +use constant CONFIG_DATA => config_data();
> +
>  use File::Find qw(finddepth);
> -use File::Spec::Functions qw(catfile);
> +use File::Spec::Functions qw(catfile catdir);
>  use Getopt::Long qw(GetOptions);
> +use File::Basename;
>  use Config;
> +use Symbol;
> 
>  use constant STARTUP_TIMEOUT => 300; # secs (good for extreme debug cases)
>  use subs qw(exit_shell exit_perl);
> 
> +die 'Could not find a suitable Apache::TestConfigData'
> +    unless defined CONFIG_DATA;
> +
>  my %core_files  = ();
>  my %original_t_perms = ();
> 
>  my @std_run      = qw(start-httpd run-tests stop-httpd);
> -my @others       = qw(verbose configure clean help ssl http11);
> +my @others       = qw(verbose configure clean help ssl http11 save);
>  my @flag_opts    = (@std_run, @others);
>  my @string_opts  = qw(order trace);
>  my @ostring_opts = qw(proxy ping);
> @@ -55,6 +105,7 @@
>     'ssl'             => 'run tests through ssl',
>     'proxy'           => 'proxy requests (default proxy is localhost)',
>     'trace=T'         => 'change tracing default to: warning, notice, info, debug, ...',
> +   'save'            => 'save test paramaters into Apache::TestConfigData',
>     (map { $_, "\U$_\E url" } @request_opts),
>  );
> 
> @@ -407,6 +458,8 @@
>      $test_config->cmodules_configure;
>      $test_config->generate_httpd_conf;
>      $test_config->save;
> +    $self->write_config() if
> +        (not %{$Apache::TestConfigData} or $self->{opts}->{save});
>  }
> 
>  sub try_exit_opts {
> @@ -509,6 +562,10 @@
> 
>  sub new_test_config {
>      my $self = shift;
> +    for (qw(httpd port user group apxs)) {
> +        next unless $Apache::TestConfigData->{$_};
> +        $self->{conf_opts}->{$_} ||= $Apache::TestConfigData->{$_};
> +    }

Just a sanity check, the env var overrides (.e.g. USER) come in later, right?

> +sub write_config {
> +    my $self = shift;
> +    my $fh = Symbol::gensym();
> +    my $vars = $self->{test_config}->{vars};
> +    my $conf_opts = $self->{conf_opts};
> +    my $file = IN_APACHE_TEST ?
> +	catfile($vars->{top_dir}, CONFIG_DATA) :
> +	CONFIG_DATA;
> +    die "Cannot open $file: $!" unless (open($fh, ">$file"));
> +    warn "Writing $file.\n";
> +    my $config_dump = '';
> +    if ($self->{test_config}->{vars}->{httpd}) {
> +	for (qw(group user apxs port httpd)) {
> +	    next unless my $var = $conf_opts->{$_} || $vars->{$_};
> +	    $config_dump .= qq{    '$_' => } . qq{'$var',\n};
> +	}
> +    }

more indentation...

what else do we miss in this implementation (besides $HOME)?

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: need help to add per-user config to Apache::Test

Posted by Randy Kobes <ra...@theoryx5.uwinnipeg.ca>.
On Wed, 3 Sep 2003, Stas Bekman wrote:

> Randy Kobes wrote:
> > On Tue, 2 Sep 2003, Stas Bekman wrote:
[ .. ]
> It should work during 'make test' as well, since it already runs t/TEST
> -config. And also whenever you provide any options to t/TEST it reconfigures,
> so I believe the normal run will do the same:
>
>   t/TEST -save -httpd /usr/local/httpd/bin/httpd
>
> I haven't tested that though.

I've checked that (with the diff below), and it seems to
work now as you say, both within Apache-Test and for a 3rd
party package. Without the -save the new -httpd is used,
but not saved into Apache::TestConfigData.
[ .. ]
> > Good idea - that's much simpler. The following assumes
> > that an empty Apache/TestConfigData.pm is present, and
> > then, as you say, 'make install' will pick up any changes
> > that have been made to it.
>
> If I remember correctly 'make install' will complain about
> the mismatch in sizes since 'make' has already put the
> files into blib? Did it work for you just fine? Purhaps we
> do need to update the two.

On linux, I tried installing Apache-Test, and then changing
the settings via
   t/TEST -save -httpd /path/to/some/other/httpd
This wrote a new lib/Apache/TestConfigData.pm, and
   make install
did recognize the change, copied it over to blib/, and
installed the new copy.

The diff below also includes a change to better get the
location of Apache::TestConfigData.
==============================================================
Index: lib/Apache/TestRun.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestRun.pm,v
retrieving revision 1.113
diff -u -r1.113 TestRun.pm
--- lib/Apache/TestRun.pm	22 Jul 2003 11:21:36 -0000	1.113
+++ lib/Apache/TestRun.pm	4 Sep 2003 21:02:44 -0000
@@ -11,19 +11,69 @@
 use Apache::TestHarness ();
 use Apache::TestTrace;

+use constant WIN32 => Apache::TestConfig::WIN32;
+require Win32 if WIN32;
+
+use Cwd;
+# Are we building things within Apache-Test?
+sub in_apache_test {
+    my $cwd =  WIN32 ? Win32::GetLongPathName(cwd) : cwd;
+    return ($cwd =~ m{Apache-Test}) ? 1 : 0;
+}
+use constant IN_APACHE_TEST => in_apache_test();
+
+require File::Spec;
+# routine to determine where the configuration file
+# Apache::TestConfigData lives. The order searched is
+# 1) a path within Apache-Test, if we are building things there
+# 2) an $ENV{HOME}/.apache-test/ directory;
+# 3) somewhere in @INC, other than a path within Apache-Test.
+sub config_data {
+    my $sys_config;
+    my $file = 'TestConfigData.pm';
+    for (@INC) {
+	my $candidate = File::Spec->catfile($_, 'Apache', $file);
+	if (-e $candidate) {
+	    $sys_config = $candidate;
+	    last;
+	}
+    }
+    if ($sys_config) {
+	eval {require $sys_config};
+	return $sys_config if (not $@ and IN_APACHE_TEST);
+	$sys_config = undef if $@;
+    }
+    # XXX $ENV{HOME} isn't propagated in mod_perl
+    if ($ENV{HOME}) {
+	my $priv_config = File::Spec->catfile($ENV{HOME},
+					      '.apache-test',
+					      $file);
+        eval {require $priv_config};
+	return $priv_config unless $@;
+    }
+    return $sys_config ? $sys_config : undef;
+}
+
+use constant CONFIG_DATA => config_data();
+
 use File::Find qw(finddepth);
-use File::Spec::Functions qw(catfile);
+use File::Spec::Functions qw(catfile catdir);
 use Getopt::Long qw(GetOptions);
+use File::Basename;
 use Config;
+use Symbol;

 use constant STARTUP_TIMEOUT => 300; # secs (good for extreme debug cases)
 use subs qw(exit_shell exit_perl);

+die 'Could not find a suitable Apache::TestConfigData'
+    unless defined CONFIG_DATA;
+
 my %core_files  = ();
 my %original_t_perms = ();

 my @std_run      = qw(start-httpd run-tests stop-httpd);
-my @others       = qw(verbose configure clean help ssl http11);
+my @others       = qw(verbose configure clean help ssl http11 save);
 my @flag_opts    = (@std_run, @others);
 my @string_opts  = qw(order trace);
 my @ostring_opts = qw(proxy ping);
@@ -55,6 +105,7 @@
    'ssl'             => 'run tests through ssl',
    'proxy'           => 'proxy requests (default proxy is localhost)',
    'trace=T'         => 'change tracing default to: warning, notice, info, debug, ...',
+   'save'            => 'save test paramaters into Apache::TestConfigData',
    (map { $_, "\U$_\E url" } @request_opts),
 );

@@ -407,6 +458,8 @@
     $test_config->cmodules_configure;
     $test_config->generate_httpd_conf;
     $test_config->save;
+    $self->write_config() if
+        (not %{$Apache::TestConfigData} or $self->{opts}->{save});
 }

 sub try_exit_opts {
@@ -509,6 +562,10 @@

 sub new_test_config {
     my $self = shift;
+    for (qw(httpd port user group apxs)) {
+        next unless $Apache::TestConfigData->{$_};
+        $self->{conf_opts}->{$_} ||= $Apache::TestConfigData->{$_};
+    }
     Apache::TestConfig->new($self->{conf_opts});
 }

@@ -614,6 +671,7 @@
     $self->run_tests;

     $self->stop;
+
 }

 my @oh = qw(jeez golly gosh darn shucks dangit rats nuts dangnabit crap);
@@ -915,6 +973,41 @@
 #    require Carp;
 #    Carp::cluck('exiting');
     CORE::exit $_[0];
+}
+
+sub write_config {
+    my $self = shift;
+    my $fh = Symbol::gensym();
+    my $vars = $self->{test_config}->{vars};
+    my $conf_opts = $self->{conf_opts};
+    my $file = IN_APACHE_TEST ?
+	catfile($vars->{top_dir}, CONFIG_DATA) :
+	CONFIG_DATA;
+    die "Cannot open $file: $!" unless (open($fh, ">$file"));
+    warn "Writing $file.\n";
+    my $config_dump = '';
+    if ($self->{test_config}->{vars}->{httpd}) {
+	for (qw(group user apxs port httpd)) {
+	    next unless my $var = $conf_opts->{$_} || $vars->{$_};
+	    $config_dump .= qq{    '$_' => } . qq{'$var',\n};
+	}
+    }
+    my $pkg = << "EOC";
+package Apache::TestConfigData;
+\$Apache::TestConfigData = {
+$config_dump
+};
+1;
+
+=head1 NAME
+
+Apache::TestConfigData - Configuration file for Apache::Test
+
+=cut
+EOC
+    print $fh $pkg;
+    close $fh;
+    return 1;
 }

 1;
======================================================================
-- 
best regards,
randy kobes


Re: need help to add per-user config to Apache::Test

Posted by Stas Bekman <st...@stason.org>.
Randy Kobes wrote:
> On Tue, 2 Sep 2003, Stas Bekman wrote:
> 
> 
>>Randy Kobes wrote:
> 
> [ .. ]
> 
>>Very good, a few more comments following
>>
>>
>>>===========================================================
>>>Index: TestRun.pm
>>
>>[...]
>> > +    $self->write_config() if
>>
>>probably better to do that right after $self->configure is
>>completed, as the very last thing in:
>>Apache::TestRun::configure
> 
> 
> OK - this is done in the diff at the end. For this, to
> override a setting within Apache::TestConfigData from some
> external package, one has to do
>    t/TEST -config -save -httpd /usr/local/httpd/bin/httpd

It should work during 'make test' as well, since it already runs t/TEST 
-config. And also whenever you provide any options to t/TEST it reconfigures, 
so I believe the normal run will do the same:

  t/TEST -save -httpd /usr/local/httpd/bin/httpd

I haven't tested that though.

>>>+    my $file = catfile($dir, 'TestConfigData.pm');
>>>+    unless (open($fh, ">$file")) {
>>>+        warn "Cannot open $file: $!";
>>>+        return;
>>>+    }
> 
> [ .. ]
> 
>>Ahm, so you write that file twice if inside the
>>Apache-Test build dir because Makefile.PL has been run
>>long time ago. We will have problems with MakeMaker
>>picking this file for 'make install', so we must provide a
>>placeholder for that file. I suppose
>>Apache/TestConfigData.pm always needs to be in the
>>distribution but include an empty:
>>
>>   $Apache::TestConfigData = {};
>>
>>So now instead of trying to eval {} for the module in @_
>>we can simply require it, and then test whether
>>%$Apache::TestConfigData has something in it?
> 
> 
> Good idea - that's much simpler. The following assumes
> that an empty Apache/TestConfigData.pm is present, and
> then, as you say, 'make install' will pick up any changes
> that have been made to it.

If I remember correctly 'make install' will complain about the mismatch in 
sizes since 'make' has already put the files into blib? Did it work for you 
just fine? Purhaps we do need to update the two.

Otherwise looks good ;)

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: need help to add per-user config to Apache::Test

Posted by Randy Kobes <ra...@theoryx5.uwinnipeg.ca>.
On Tue, 2 Sep 2003, Stas Bekman wrote:

> Randy Kobes wrote:
[ .. ]
> Very good, a few more comments following
>
> > ===========================================================
> > Index: TestRun.pm
> [...]
>  > +    $self->write_config() if
>
> probably better to do that right after $self->configure is
> completed, as the very last thing in:
> Apache::TestRun::configure

OK - this is done in the diff at the end. For this, to
override a setting within Apache::TestConfigData from some
external package, one has to do
   t/TEST -config -save -httpd /usr/local/httpd/bin/httpd

> [...]
> > +use Symbol qw(gensym);
> [...]
> > +    my $fh = Symbol::gensym();
>
> then probably don't need to import it.

Right - thanks.

> > +    my $file = catfile($dir, 'TestConfigData.pm');
> > +    unless (open($fh, ">$file")) {
> > +        warn "Cannot open $file: $!";
> > +        return;
> > +    }
[ .. ]
> Ahm, so you write that file twice if inside the
> Apache-Test build dir because Makefile.PL has been run
> long time ago. We will have problems with MakeMaker
> picking this file for 'make install', so we must provide a
> placeholder for that file. I suppose
> Apache/TestConfigData.pm always needs to be in the
> distribution but include an empty:
>
>    $Apache::TestConfigData = {};
>
> So now instead of trying to eval {} for the module in @_
> we can simply require it, and then test whether
> %$Apache::TestConfigData has something in it?

Good idea - that's much simpler. The following assumes
that an empty Apache/TestConfigData.pm is present, and
then, as you say, 'make install' will pick up any changes
that have been made to it.
===============================================================
Index: lib/Apache/TestRun.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestRun.pm,v
retrieving revision 1.113
diff -u -r1.113 TestRun.pm
--- lib/Apache/TestRun.pm	22 Jul 2003 11:21:36 -0000	1.113
+++ lib/Apache/TestRun.pm	3 Sep 2003 06:56:29 -0000
@@ -11,10 +11,54 @@
 use Apache::TestHarness ();
 use Apache::TestTrace;

+use constant WIN32 => Apache::TestConfig::WIN32;
+require Win32 if WIN32;
+
+use Cwd;
+# Are we building things within Apache-Test?
+sub in_apache_test {
+    my $cwd =  WIN32 ? Win32::GetLongPathName(cwd) : cwd;
+    return ($cwd =~ m{Apache-Test}) ? 1 : 0;
+}
+use constant IN_APACHE_TEST => in_apache_test();
+
+require File::Spec;
+# routine to determine where the configuration file
+# Apache::TestConfigData lives. The order searched is
+# 1) a path within Apache-Test, if we are building things there
+# 2) an $ENV{HOME}/.apache-test/ directory;
+# 3) somewhere in @INC, other than a path within Apache-Test.
+sub config_data {
+    my $config;
+    my $file = 'TestConfigData.pm';
+    for (@INC) {
+	my $candidate = File::Spec->catfile($_, 'Apache', $file);
+	if (-e $candidate) {
+	    $config = $candidate;
+	    last;
+	}
+    }
+    eval {require $config};
+    return $config if (not $@ and IN_APACHE_TEST);
+    # XXX $HOME isn't propagated in mod_perl
+    if ($ENV{HOME}) {
+	$config = File::Spec->catfile($ENV{HOME},
+				      '.apache-test',
+				      $file);
+        eval {require $config};
+	return $config unless $@;
+    }
+    return $@ ? undef : $config;
+}
+
+use constant CONFIG_DATA => config_data();
+
 use File::Find qw(finddepth);
-use File::Spec::Functions qw(catfile);
+use File::Spec::Functions qw(catfile catdir);
 use Getopt::Long qw(GetOptions);
+use File::Basename;
 use Config;
+use Symbol;

 use constant STARTUP_TIMEOUT => 300; # secs (good for extreme debug cases)
 use subs qw(exit_shell exit_perl);
@@ -23,7 +67,7 @@
 my %original_t_perms = ();

 my @std_run      = qw(start-httpd run-tests stop-httpd);
-my @others       = qw(verbose configure clean help ssl http11);
+my @others       = qw(verbose configure clean help ssl http11 save);
 my @flag_opts    = (@std_run, @others);
 my @string_opts  = qw(order trace);
 my @ostring_opts = qw(proxy ping);
@@ -55,6 +99,7 @@
    'ssl'             => 'run tests through ssl',
    'proxy'           => 'proxy requests (default proxy is localhost)',
    'trace=T'         => 'change tracing default to: warning, notice, info, debug, ...',
+   'save'            => 'save test paramaters into Apache::TestConfigData',
    (map { $_, "\U$_\E url" } @request_opts),
 );

@@ -407,6 +452,8 @@
     $test_config->cmodules_configure;
     $test_config->generate_httpd_conf;
     $test_config->save;
+    $self->write_config() if
+        (IN_APACHE_TEST or $self->{opts}->{save});
 }

 sub try_exit_opts {
@@ -509,6 +556,10 @@

 sub new_test_config {
     my $self = shift;
+    for (qw(httpd port user group apxs)) {
+        next unless $Apache::TestConfigData->{$_};
+        $self->{conf_opts}->{$_} ||= $Apache::TestConfigData->{$_};
+    }
     Apache::TestConfig->new($self->{conf_opts});
 }

@@ -614,6 +665,7 @@
     $self->run_tests;

     $self->stop;
+
 }

 my @oh = qw(jeez golly gosh darn shucks dangit rats nuts dangnabit crap);
@@ -915,6 +967,39 @@
 #    require Carp;
 #    Carp::cluck('exiting');
     CORE::exit $_[0];
+}
+
+sub write_config {
+    my $self = shift;
+    my $fh = Symbol::gensym();
+    my $vars = $self->{test_config}->{vars};
+    my $file = IN_APACHE_TEST ?
+	catfile($vars->{top_dir}, CONFIG_DATA) :
+	CONFIG_DATA;
+    die "Cannot open $file: $!" unless (open($fh, ">$file"));
+    warn "Writing $file.\n";
+    my $config_dump;
+    for (qw(group user apxs port httpd)) {
+        next unless $vars->{$_};
+        $config_dump .= qq{    '$_' => } . qq{'$vars->{$_}',\n};
+    }
+
+    my $pkg = << "EOC";
+package Apache::TestConfigData;
+\$Apache::TestConfigData = {
+$config_dump
+};
+1;
+
+=head1 NAME
+
+Apache::TestConfigData - Configuration file for Apache::Test
+
+=cut
+EOC
+    print $fh $pkg;
+    close $fh;
+    return 1;
 }

 1;
=================================================================

-- 
best regards,
randy

Re: need help to add per-user config to Apache::Test

Posted by Stas Bekman <st...@stason.org>.
Randy Kobes wrote:
> On Tue, 2 Sep 2003, Stas Bekman wrote:
> 
> 
>>Randy Kobes wrote:
> 
> [ ... ]
> 
>>> sub filter_args {
>>>     my($args, $wanted_args) = @_;
>>>+    if (HAS_CONFIG) {
>>>+        for (qw(group user apxs port httpd)) {
>>>+            next unless defined $Apache::MyTestConfig->{$_};
>>>+            unshift @$args, "-$_", $Apache::MyTestConfig->{$_};
>>>+        }
>>>+    }
>>
>>may be it's better to do it at a later stage? this just
>>used to generate t/TEST and similar scripts. If MyConfig
>>has changed since t/TEST was generated the changes won't
>>affect t/TEST.
> 
> [ .. ]
> 
> Thanks, Stas. You're right about the problems with $HOME,
> and I'll take a more careful look at it, as well as your
> other comments. In the meantime, here's something that
> inserts the data at a later stage, and yet still can get
> overridden by explicit arguments to t/TEST. In this
> attempt, all the changes are made to Apache::TestRun.pm.

Very good, a few more comments following

> ===========================================================
> Index: TestRun.pm
[...]
 > +    $self->write_config() if

probably better to do that right after $self->configure is completed, as the 
very last thing in: Apache::TestRun::configure

Notice that it already saves the data, but we don't want most of it. See 
Apache::TestConfig::save, it saves the data in the local file: 
t/conf/apache_test_config.pm

[...]
> +use Symbol qw(gensym);
[...]
> +    my $fh = Symbol::gensym();

then probably don't need to import it.

> +    my $file = catfile($dir, 'TestConfigData.pm');
> +    unless (open($fh, ">$file")) {
> +        warn "Cannot open $file: $!";
> +        return;
> +    }
> +    warn "Writing $file ....\n";
> +    my $vars = $self->{test_config}->{vars};
> +    my $config_dump;
> +    for (qw(group user apxs port httpd)) {
> +        next unless $vars->{$_};
> +        $config_dump .= qq{    '$_' => } . qq{'$vars->{$_}',\n};
> +    }
> +
> +    my $pkg = << "EOC";
> +package Apache::TestConfigData;
> +\$Apache::TestConfigData = {
> +$config_dump
> +};
> +1;
[...]
> +EOC
> +    print $fh $pkg;
> +    close $fh;
> +    my $test = catdir($vars->{top_dir}, 'blib/lib/Apache');
> +    if (-e catfile($test, 'Test.pm')) {
> +        my $fh = Symbol::gensym();
> +        my $file = catfile($test, 'TestConfigData.pm');
> +        if (-e $file) {
> +            unlink $file or do {
> +                warn "Cannot unlink $file: $!";
> +                return;

why not a fatal error? It should normally always work, not?

> +            }
> +        }
> +        unless (open($fh, ">$file")) {
> +            warn "Cannot open $file: $!";
> +            return;
> +        }

same here.

> +        print $fh $pkg;
> +        close $fh;

Ahm, so you write that file twice if inside the Apache-Test build dir because 
Makefile.PL has been run long time ago. We will have problems with MakeMaker 
picking this file for 'make install', so we must provide a placeholder for 
that file. I suppose Apache/TestConfigData.pm always needs to be in the 
distribution but include an empty:

   $Apache::TestConfigData = {};

So now instead of trying to eval {} for the module in @_ we can simply require 
it, and then test whether %$Apache::TestConfigData has something in it?

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: need help to add per-user config to Apache::Test

Posted by Randy Kobes <ra...@theoryx5.uwinnipeg.ca>.
On Tue, 2 Sep 2003, Stas Bekman wrote:

> Randy Kobes wrote:
[ ... ]
> >  sub filter_args {
> >      my($args, $wanted_args) = @_;
> > +    if (HAS_CONFIG) {
> > +        for (qw(group user apxs port httpd)) {
> > +            next unless defined $Apache::MyTestConfig->{$_};
> > +            unshift @$args, "-$_", $Apache::MyTestConfig->{$_};
> > +        }
> > +    }
>
> may be it's better to do it at a later stage? this just
> used to generate t/TEST and similar scripts. If MyConfig
> has changed since t/TEST was generated the changes won't
> affect t/TEST.
[ .. ]

Thanks, Stas. You're right about the problems with $HOME,
and I'll take a more careful look at it, as well as your
other comments. In the meantime, here's something that
inserts the data at a later stage, and yet still can get
overridden by explicit arguments to t/TEST. In this
attempt, all the changes are made to Apache::TestRun.pm.
===========================================================
Index: TestRun.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestRun.pm,v
retrieving revision 1.113
diff -u -r1.113 TestRun.pm
--- TestRun.pm	22 Jul 2003 11:21:36 -0000	1.113
+++ TestRun.pm	2 Sep 2003 22:31:40 -0000
@@ -11,10 +11,31 @@
 use Apache::TestHarness ();
 use Apache::TestTrace;

+require File::Spec;
+sub has_config {
+    my $has_config = 0;
+    # XXX $HOME isn't propagated in mod_perl
+    if ($ENV{HOME}) {
+        eval
+            {require File::Spec->catfile($ENV{HOME},
+                                         '.apache-test',
+					 'TestConfigData.pm');};
+        $has_config = 1 unless $@;
+    }
+    unless ($has_config) {
+        eval {require Apache::TestConfigData;};
+        $has_config = 1 unless $@;
+    }
+    return $has_config;
+}
+use constant HAS_CONFIG => has_config();
+
 use File::Find qw(finddepth);
-use File::Spec::Functions qw(catfile);
+use File::Spec::Functions qw(catfile catdir);
 use Getopt::Long qw(GetOptions);
+use File::Basename;
 use Config;
+use Symbol qw(gensym);

 use constant STARTUP_TIMEOUT => 300; # secs (good for extreme debug cases)
 use subs qw(exit_shell exit_perl);
@@ -23,7 +44,7 @@
 my %original_t_perms = ();

 my @std_run      = qw(start-httpd run-tests stop-httpd);
-my @others       = qw(verbose configure clean help ssl http11);
+my @others       = qw(verbose configure clean help ssl http11 save);
 my @flag_opts    = (@std_run, @others);
 my @string_opts  = qw(order trace);
 my @ostring_opts = qw(proxy ping);
@@ -55,6 +76,7 @@
    'ssl'             => 'run tests through ssl',
    'proxy'           => 'proxy requests (default proxy is localhost)',
    'trace=T'         => 'change tracing default to: warning, notice, info, debug, ...',
+   'save'            => 'save test paramaters into Apache::TestConfigData',
    (map { $_, "\U$_\E url" } @request_opts),
 );

@@ -509,6 +531,12 @@

 sub new_test_config {
     my $self = shift;
+    if (HAS_CONFIG) {
+        for (qw(httpd port user group apxs)) {
+            next unless $Apache::TestConfigData->{$_};
+	    $self->{conf_opts}->{$_} ||= $Apache::TestConfigData->{$_};
+        }
+    }
     Apache::TestConfig->new($self->{conf_opts});
 }

@@ -614,6 +642,10 @@
     $self->run_tests;

     $self->stop;
+
+    $self->write_config() if
+        ($self->{opts}->{save} or not HAS_CONFIG);
+
 }

 my @oh = qw(jeez golly gosh darn shucks dangit rats nuts dangnabit crap);
@@ -915,6 +947,75 @@
 #    require Carp;
 #    Carp::cluck('exiting');
     CORE::exit $_[0];
+}
+
+sub write_config {
+    my $self = shift;
+    my $dir;
+    for (@INC) {
+        my $candidate = catfile($_, 'Apache', 'Test.pm');
+        if (-e $candidate) {
+            $dir = dirname($candidate);
+            last;
+        }
+    }
+    unless (-w $dir) {
+        $dir = catdir($ENV{HOME}, '.apache-test');
+        unless (-d $dir) {
+            mkdir $dir or do {
+                warn "Cannot mkdir $dir: $!";
+                return;
+            };
+        }
+    }
+
+    my $fh = Symbol::gensym();
+    my $file = catfile($dir, 'TestConfigData.pm');
+    unless (open($fh, ">$file")) {
+        warn "Cannot open $file: $!";
+        return;
+    }
+    warn "Writing $file ....\n";
+    my $vars = $self->{test_config}->{vars};
+    my $config_dump;
+    for (qw(group user apxs port httpd)) {
+        next unless $vars->{$_};
+        $config_dump .= qq{    '$_' => } . qq{'$vars->{$_}',\n};
+    }
+
+    my $pkg = << "EOC";
+package Apache::TestConfigData;
+\$Apache::TestConfigData = {
+$config_dump
+};
+1;
+
+=head1 NAME
+
+Apache::TestConfigData - Configuration file for Apache::Test
+
+=cut
+EOC
+    print $fh $pkg;
+    close $fh;
+    my $test = catdir($vars->{top_dir}, 'blib/lib/Apache');
+    if (-e catfile($test, 'Test.pm')) {
+        my $fh = Symbol::gensym();
+        my $file = catfile($test, 'TestConfigData.pm');
+        if (-e $file) {
+            unlink $file or do {
+                warn "Cannot unlink $file: $!";
+                return;
+            }
+        }
+        unless (open($fh, ">$file")) {
+            warn "Cannot open $file: $!";
+            return;
+        }
+        print $fh $pkg;
+        close $fh;
+    }
+    return 1;
 }

 1;
===================================================================
-- 
best regards,
randy

Re: need help to add per-user config to Apache::Test

Posted by Stas Bekman <st...@stason.org>.
Randy Kobes wrote:
> [ trimmed mod_perl mailing list from cc ]
> 
> On Fri, 29 Aug 2003, Randy Kobes wrote:
> 
> 
>>On Thu, 28 Aug 2003, Stas Bekman wrote:
>>
>>
>>>Several people have asked for having a new feature in
>>>Apache::Test: they want to configure it once (where the
>>>server, apxs, etx are) and run Apache::Test without
>>>needing to pass any arguments. Matt suggested that it
>>>should remember the values passed the first time it's used
>>>and then re-use them. However on a system with several
>>>users and different preferences, this won't work.
>>>Therefore we need to be able to support per-user
>>>preferences. CPAN.pm's setup seems to provide a good
>>>solution to the same problem (CPAN/Config.pm and
>>>~user/.cpan/CPAN/Config.pm). So I thought that someone
>>>would like to port the functionality from CPAN.pm to
>>>Apache::Test and send the patches here. It's all pure
>>>perl, so you have no excuses that it's XS/C ;)
>>
>>I have a mostly functional version of this, save for
>>the ability to use a $HOME/.apache-test/Config.pm, which
>>shouldn't be too hard to add. I'll try to finish it
>>off this weekend.
> 
> 
> A stab at this follows ... It's rough, as I wanted to
> make sure this was on the right track; basically, what's
> supposed to happen is
> - if a Apache::MyTestConfig is found, use the values for

Apache::TestMyConfig? so that we keep all Apache/Test*.pm and it's My Config, 
not My Test... but see below

> apxs, httpd, user, group, and port stored in there. These
> values get overridden if they appear as arguments to 'perl
> Makefile.PL'.

which embeds them in t/TEST, so in effect if they are passed to the code that 
runs a subclass of Apache::TestRun

> - if no Apache::MyTestConfig is present, or a '-save'
> option is passed to 'perl t/TEST', Apache::MyTestConfig
> is created, and then installed.
> - the location of Apache::MyTestConfig is, first of all,
> under $HOME/.apache-test/, or if this is not present,
> under the system @INC.

If it's under system-wide @INC, it probably should be called My because it's 
not user specific (I'm trying to mimic CPAN.pm here. BTW, I haven't been using 
CPANPLUS, how do they do it?) But then it'll collide with the existing 
Apache/TestConfig.pm. So may be we just have Apache/TestConfigData.pm (or 
something like that) and then we don't need My at all, as we will just look 
first under $HOME/.apache-test and then under @INC?

I think when Apache::Test is installed, the config data module should go into 
@INC's location. when it's used for the first time it should go into 
$HOME/.apache-test/.

Won't ~/.apache-test have probs on some filesystems? Is it a safe path?

> I'm not sure I'm putting the values of
> Apache::MyTestConfig in the right, or best, place;
> I haven't tested it extensively, as my linux box
> is a live server.
> 
> =========================================================
> Index: TestConfig.pm
> ===================================================================
> RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfig.pm,v
> retrieving revision 1.171
> diff -u -r1.171 TestConfig.pm
> --- TestConfig.pm	13 Aug 2003 19:02:51 -0000	1.171
> +++ TestConfig.pm	1 Sep 2003 03:51:13 -0000
> @@ -3,6 +3,22 @@
>  use strict;
>  use warnings FATAL => 'all';
> 
> +require File::Spec;
> +sub has_config {
> +    my $has_config = 0;
> +    if ($ENV{HOME}) {
> +        eval
> +            {require File::Spec->catfile($ENV{HOME},
> +                                         '.apache-test', 'MyTestConfig.pm');};

That won't work when invoked from the server side, since HOME isn't normally 
propogated. Probably need to detect whether we are running under mod_perl 2.0 
and then retrieve the username the server is running under, but wait, normally 
it runs under 'nobody' or a such, so it won't have this setup...

in any case for now you probably need to check first whether $ENV{HOME} exists 
and put some XXX to fix it later so it'll work under mod_perl as well...

> @@ -24,8 +40,8 @@
>  use File::Path ();
>  use File::Spec::Functions qw(catfile abs2rel splitdir canonpath
>                               catdir file_name_is_absolute);
> -use Cwd qw(fastcwd);
> 
> +use Cwd qw(fastcwd);

weird...

>  use Apache::TestConfigPerl ();
>  use Apache::TestConfigParse ();
>  use Apache::TestTrace;
> @@ -34,6 +50,8 @@
> 
>  use vars qw(%Usage);
> 
> +use constant HAS_CONFIG => has_config();
> +
>  %Usage = (
>     top_dir       => 'top-level directory (default is $PWD)',
>     t_dir         => 'the t/ test directory (default is $top_dir/t)',
> @@ -72,6 +90,12 @@
> 
>  sub filter_args {
>      my($args, $wanted_args) = @_;
> +    if (HAS_CONFIG) {
> +        for (qw(group user apxs port httpd)) {
> +            next unless defined $Apache::MyTestConfig->{$_};
> +            unshift @$args, "-$_", $Apache::MyTestConfig->{$_};
> +        }
> +    }

may be it's better to do it at a later stage? this just used to generate 
t/TEST and similar scripts. If MyConfig has changed since t/TEST was generated 
the changes won't affect t/TEST.

>      my(@pass, %keep);
> 
>      my @filter = @$args;
> Index: TestRun.pm
> ===================================================================
[...]
> +    $self->write_config() if
> +        ($self->{opts}->{save} || not HAS_CONFIG);

Do you mind to have 'or not' or '|| !' ;)

> +
>  }
> 
>  my @oh = qw(jeez golly gosh darn shucks dangit rats nuts dangnabit crap);
> @@ -915,6 +924,75 @@
>  #    require Carp;
>  #    Carp::cluck('exiting');
>      CORE::exit $_[0];
> +}
> +
> +sub write_config {
> +    my $self = shift;
> +    my $dir;
> +    for (@INC) {
> +        my $candidate = catfile($_, 'Apache', 'Test.pm');
> +        if (-e $candidate) {
> +            $dir = dirname($candidate);
> +            last;
> +        }
> +    }
> +    unless (-w $dir) {
> +        $dir = catdir($ENV{HOME}, '.apache-test');
> +        unless (-d $dir) {
> +            mkdir $dir or do {
> +                warn "Cannot mkdir $dir: $!";
> +                return;
> +            };
> +        }
> +    }

Probably this should be an explicit attempt to write to ~/.apache-test if run 
as non-root, since it'll most likely fail to write to the system-wide @INC. Of 
course it may have a local non-root libs, in @INC.  And we can simplify this 
further by creating  Apache/TestConfigData.pm (or whatever we call it), when 
we install Apache::Test for the first time. So we don't have to look for 
Apache/Test.pm. So it'll just have:

+    my $pkg = << "EOC";
+package Apache::MyTestConfig;
+\$Apache::MyTestConfig = {
+};
+1;
+
+=head1 NAME
+
+Apache::MyTestConfig - Configuration file for Apache::Test
+
+=cut
+EOC

or may be having all the keys, but just no values?

+    for (qw(group user apxs port httpd)) {
+        next unless $vars->{$_};
+        $config_dump .= "$_ => ''\n";
+    }

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com