Revision: 121 Author: matt Date: 2006-08-24 15:11:27 +0000 (Thu, 24 Aug 2006)
Log Message: ----------- Start of a test framework Added Paths: ----------- trunk/lib/AxKit2/Test.pm trunk/plugins/logging/file Added: trunk/lib/AxKit2/Test.pm =================================================================== --- trunk/lib/AxKit2/Test.pm 2006-08-24 13:33:14 UTC (rev 120) +++ trunk/lib/AxKit2/Test.pm 2006-08-24 15:11:27 UTC (rev 121) @@ -0,0 +1,149 @@ +# Copyright 2001-2006 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package AxKit2::Test; + +use strict; +use warnings; + +use IO::Socket; +use base 'Exporter'; + +our @EXPORT = qw(start_server); + +# Module to assist with testing + +my $server_port = 54000; + +sub get_free_port { + die "No ports free" if $server_port == 65534; + + while (IO::Socket::INET->new(PeerAddr => "localhost:$server_port")) { + $server_port++; + } + if (IO::Socket::INET->new(PeerAddr => "localhost", PeerPort => $server_port+1)) { + # server port free, console port isn't + $server_port += 2; + return get_free_port(); + } + return $server_port; +} + +sub start_server { + my $config = shift; + + my $port = get_free_port(); + + return AxKit2::Test::Server->new($port, $config); +} + + +package AxKit2::Test::Server; + +use File::Temp qw(tempfile); +use AxKit2; + +sub new { + my $class = shift; + my ($port, $config) = @_; + + my ($fh, $filename) = tempfile(); + + my $self = bless { + port => $port, + console_port => $port + 1, + config_file => $filename, + }, $class; + + $self->setup_config($fh, $config); + + my $child = fork; + die "fork failed" unless defined $child; + if ($child) { + $self->{child_pid} = $child; + return $self; + } + + # child + AxKit2->run($filename); + exit; +} + +sub setup_config { + my ($self, $fh, $config) = @_; + + my $port = $self->{port}; + my $console = $self->{console_port}; + + print $fh <<EOT; +Plugin logging/file +LogFile test.log +LogLevel LOGDEBUG + +# setup console +ConsolePort $console +Plugin stats + +Plugin error_xml +ErrorStylesheet demo/error.xsl +StackTrace On + +<Server testserver> + Port $port + +EOT + print $fh $config; + + print $fh <<EOT; + +</Server> +EOT + + seek($fh, 0, 0); +} + +sub DESTROY { + my $self = shift; + + $self->shutdown; +} + +sub shutdown { + my $self = shift; + + return unless $self->{child_pid}; + + my $conf = IO::Socket::INET->new( + PeerAddr => "127.0.0.1", + PeerPort => $self->{console_port}, + ) || die "Cannot connect to console port $self->{console_port} : $!"; + + IO::Handle::blocking($conf, 0); + + $conf->print("shutdown\n"); + + my $buf; + read($conf, $buf, 128 * 1024); + + use POSIX ":sys_wait_h"; + my $kid; + do { + $kid = waitpid(-1, WNOHANG); + } until $kid > 0; + + unlink($self->{config_file}); +} + +1; Added: trunk/plugins/logging/file =================================================================== --- trunk/plugins/logging/file 2006-08-24 13:33:14 UTC (rev 120) +++ trunk/plugins/logging/file 2006-08-24 15:11:27 UTC (rev 121) @@ -0,0 +1,111 @@ +#!/usr/bin/perl -w + +# Copyright 2001-2006 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +=head1 NAME + +logging/file - Logging plugin to send logging to a file + +=head1 SYNOPSIS + + Plugin logging/file + LogFile log.out + LogLevel LOGWARN + +=head1 DESCRIPTION + +This plugin simply sends all error logging to the file specified. + +=head1 CONFIG + +=head2 LogLevel STRING | NUMBER + +Specify the level of logging. One of: + + LOGDEBUG or 7 + LOGINFO or 6 + LOGNOTICE or 5 + LOGWARN or 4 + LOGERROR or 3 + LOGCRIT or 2 + LOGALERT or 1 + LOGEMERG or 0 + +=head2 LogFile STRING + +A file to use for logging. + +=cut + +sub init { + my $self = shift; + + $self->register_config('LogLevel', sub { $self->loglevel(@_) }); + $self->register_config('LogFile', sub { $self->logfile(@_) }); +} + +sub dor { + my $val = shift; + defined($val) ? $val : $_[0]; +} + +sub loglevel { + my ($self, $conf) = (shift, shift); + + my $key = $self->plugin_name . '::loglevel'; + + if (@_) { + my $value = shift; + if ($value !~ /^\d+$/) { + $value = AxKit2::Constants::log_level($value) + || die "Invalid log level: $value"; + } + $conf->notes($key, $value); + } + + dor($conf->notes($key), 4); +} + +sub logfile { + my $self = shift; + my $conf = shift; + + my $key = $self->plugin_name . '::logfile'; + + if (@_) { + my $filename = shift; + open(my $fh, ">>$filename") || die "open($filename): $!"; + $conf->notes($key, $fh); + } + + $conf->notes($key) || die "No log file specified"; +} + +sub hook_logging { + my ($self, $level, @args) = @_; + + if ($level <= $self->loglevel($self->config)) { + my $fh = $self->logfile($self->config); + if ($self->client->can('peer_addr_string')) { + print $fh ($self->client->peer_addr_string, " L$level ", @args, "\n"); + } + else { + print $fh ("L$level ", @args, "\n"); + } + } + + return DECLINED; +}