perl-docs-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject cvs commit: modperl-docs/src/devel/writing_tests writing_tests.pod
Date Mon, 24 Dec 2001 19:30:25 GMT
stas        01/12/24 11:30:25

  Modified:    src/devel/writing_tests writing_tests.pod
  document how to:
  - start multiple servers
  - use multiple user agents
  - hit the same interpreter
  Revision  Changes    Path
  1.25      +133 -0    modperl-docs/src/devel/writing_tests/writing_tests.pod
  Index: writing_tests.pod
  RCS file: /home/cvs/modperl-docs/src/devel/writing_tests/writing_tests.pod,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- writing_tests.pod	2001/12/24 05:47:46	1.24
  +++ writing_tests.pod	2001/12/24 19:30:25	1.25
  @@ -888,6 +888,139 @@
  +=head2 Request Generation Methods
  +META: here goes the explanation of shortcuts: GET_BODY, POST_BODY,
  +=head2 Starting Multiple Servers
  +By default the C<Apache::Test> framework sets up only a single server
  +to test against.
  +In some cases you need to have more than one server.  If this is the
  +situation, you have to override the I<maxclients> configuration
  +directive, whose default is 1. Usually this is done in C<t/TEST.PL> by
  +subclassing the parent test run class and overriding the
  +new_test_config() method. For example if the parent class is
  +C<Apache::TestRunPerl>, you can change your C<t/TEST.PL> to be:
  +  use strict;
  +  use warnings FATAL => 'all';
  +  use lib "../lib"; # test against the source lib for easier dev
  +  use lib map {("../blib/$_", "../../blib/$_")} qw(lib arch);
  +  use Apache::TestRunPerl ();
  +  package MyTest;
  +  our @ISA = qw(Apache::TestRunPerl);
  +  # subclass new_test_config to add some config vars which will be
  +  # replaced in generated httpd.conf
  +  sub new_test_config {
  +      my $self = shift;
  +      $self->{conf_opts}->{maxclients} = 2;
  +      return $self->SUPER::new_test_config;
  +  }
  +  MyTest->new->run(@ARGV);
  +=head2 Multiple User Agents
  +By default the C<Apache::Test> framework uses a single user agent
  +which talks to the server (this is the C<LWP> user agent, if you have
  +C<LWP> installed). You almost never use this agent directly in the
  +tests, but via various wrappers. However if you need a second user
  +agent you can clone these. For example:
  +  my $ua2 = Apache::TestRequest::user_agent()->clone;
  +=head2 Hitting the Same Interpreter (Server Thread/Process Instance)
  +When a single instance of the server thread/process is running, all
  +the tests go through the same server. However if the C<Apache::Test>
  +framework was configured to to run a few instances, two subsequent
  +sub-tests may not hit the same server instance. In certain tests
  +(e.g. testing the closure effect or the C<BEGIN> blocks) it's
  +important to make sure that a sequence of sub-tests are run against
  +the same server instance. The C<Apache::Test> framework supports this
  +Here is an example from C<ModPerl::Registry> closure tests. Using the
  +counter closure problem under C<ModPerl::Registry>:
  +  cgi-bin/
  +  ------------------
  +  #!perl -w
  +  print "Content-type: text/plain\r\n\r\n";
  +  # this is a closure (when compiled inside handler()):
  +  my $counter = 0;
  +  counter();
  +  sub counter {
  +      #warn "$$";
  +      print ++$counter;
  +  }
  +If this script get invoked twice in a row and we make sure that it
  +gets executed by the same server instance, the first time it'll return
  +1 and the second time 2. So here is the gist of the request part that
  +makes sure that its two subsequent requests hit the same server
  +  closure.t
  +  ---------
  +  ...
  +  my $url = "/same_interp/cgi-bin/";
  +  my $same_interp = Apache::TestRequest::same_interp_tie($url);
  +  # should be no closure effect, always returns 1
  +  my $first  = req($same_interp, $url);
  +  my $second = req($same_interp, $url);
  +  ok t_cmp(
  +      1,
  +      $first && $second && ($second - $first),
  +      "the closure problem is there",
  +  );
  +  sub req {
  +      my($same_interp, $url) = @_;
  +      my $res = Apache::TestRequest::same_interp_do($same_interp,
  +                                                    \&GET, $url);
  +      return $res ? $res->content : undef;
  +  }
  +In this test we generate two requests to I<cgi-bin/> and
  +expect the returned value to increment for each new request, because
  +of the closure problem generated by C<ModPerl::Registry>. Since we
  +don't know whether some other test has called this script already, we
  +simply check whether the substraction of the two subsequent requests'
  +outputs gives a value of 1.
  +The test starts by requesting the server to tie a single instance to
  +all requests made with a certain identifier. This is done using the
  +same_interp_tie() function which returns a unique server instance's
  +indentifier. From now on any requests made through same_interp_do()
  +and supplying this indentifier as the first argument will be served by
  +the same server instance. The second argument to same_interp_do() is
  +the method to use for generating the request and the third is the URL
  +to use. Extra arguments can be supplied if needed by the request
  +generation method (e.g. headers).
  +This technique works for testing purposes where we know that we have
  +just a few server instances. What happens internally is when
  +same_interp_tie() is called the server instance that served it returns
  +its unique UUID, so when we want to hit the same server instance in
  +subsequent requests we generate the same request until we learn that
  +we are being served by the server instance that we want. This magic is
  +done by using a fixup handler which returns C<OK> only if it sees that
  +its unique id matches. As you understand this technique would be very
  +inefficient in production with many server instances.
   =head1 How to Write Tests

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message