well, since I know andre is paying attention, I thought I'd start with mod_include :)
ok, I made some adjustments to t/modules/include.t to accommodate 1.3, 2.0, and 2.1. hopefully, all I did was shuffle things around so that it's easier to keep track of the three cases: proper behavior, in-process fixes, and will-never-be-fixed-in-this-version. for the most part, these were all documented by andre so all I ended up doing was (hopefully) making later bookeeping a bit easier for everyone. so, here are before and after outputs (note the failure numbers are different due to a new ordering): 1.3 before: modules/include....NOK 18# Failed test 18 in modules/include.t at line 127 fail #18 modules/include....NOK 35# Failed test 35 in modules/include.t at line 127 fail #35 modules/include....ok 42/76# Failed test 42 in modules/include.t at line 207 *TODO* 1.3 after: modules/include....ok 20/76# Failed test 20 in modules/include-geoff.t at line 223 fail #18 *TODO* modules/include....ok 39/76# Failed test 39 in modules/include-geoff.t at line 223 fail #37 *TODO* modules/include....ok 43/76# Failed test 43 in modules/include-geoff.t at line 272 *TODO* modules/include....ok 14/76 skipped: Skipping bucket boundary tests, no mod_bucketeer All tests successful, 14 subtests skipped. 2.0 before: modules/include....NOK 9# Failed test 9 in modules/include.t at line 127 fail #9 modules/include....NOK 18# Failed test 18 in modules/include.t at line 127 fail #18 modules/include....NOK 33# Failed test 33 in modules/include.t at line 127 fail #33 modules/include....NOK 35# Failed test 35 in modules/include.t at line 127 fail #35 modules/include....NOK 36# Failed test 36 in modules/include.t at line 127 fail #36 modules/include....NOK 41# Failed test 41 in modules/include.t at line 150 2.0 after: modules/include....ok 11/81# Failed test 11 in modules/include-geoff.t at line 223 fail #9 *TODO* modules/include....ok 22/81# Failed test 22 in modules/include-geoff.t at line 223 fail #18 *TODO* modules/include....ok 27/81# Failed test 27 in modules/include-geoff.t at line 223 fail #23 *TODO* modules/include....ok 39/81# Failed test 39 in modules/include-geoff.t at line 223 fail #35 *TODO* modules/include....ok 41/81# Failed test 41 in modules/include-geoff.t at line 223 fail #37 *TODO* modules/include....ok 42/81# Failed test 42 in modules/include-geoff.t at line 223 fail #38 *TODO* modules/include....ok 14/81 skipped: Skipping bucket boundary tests, no mod_bucketeer, 1/81 unexpectedly succeeded All tests successful (1 subtest UNEXPECTEDLY SUCCEEDED), 14 subtests skipped. 2.1 before: modules/include....ok 14/82 skipped: Skipping bucket boundary tests, no mod_bucketeer, 1/82 unexpectedly succeeded All tests successful (1 subtest UNEXPECTEDLY SUCCEEDED), 14 subtests skipped. 2.1 after: modules/include....ok 14/82 skipped: Skipping bucket boundary tests, no mod_bucketeer All tests successful, 14 subtests skipped. the only place I'm a bit confused is the flastmod/fsize test, which is marked as TODO currently but is "unexpectedly passing" in 2.0/2.1. the comments make it sound like large sizes should fail in 2.0, but I created all sizes up to 2GB and it still didn't fail (after conversions were taken into account). what is that test actually testing, the commifying and K/M/G rounding? ideally, if 2.0 is still buggy, what I'd like to see there is a tests that passes in 2.1 but fails in 2.0 so we can mark it as TODO in 2.0 as well. anyway, I know the changes are largish - certainly more than I had anticipated - but I hope it's a bit cleaner and easier to maintain. I definitely don't mean to trample on your work, so feedback is very welcome. oh, and I'm very impressed with the thoroughness of the tests, btw. nice work. --Geoff
Index: t/modules/include.t =================================================================== RCS file: /home/cvspublic/httpd-test/perl-framework/t/modules/include.t,v retrieving revision 1.45 diff -u -r1.45 include.t --- t/modules/include.t 20 Nov 2003 22:16:35 -0000 1.45 +++ t/modules/include.t 10 Dec 2003 05:34:27 -0000 @@ -5,6 +5,9 @@ use Apache::TestRequest; use Apache::TestUtil; +Apache::TestRequest::scheme('http'); #ssl not listening on this vhost +Apache::TestRequest::module('mod_include'); #use this module's port + use constant WINFU => Apache::TestConfig::WINFU; ## mod_include tests @@ -15,6 +18,9 @@ my $vars = Apache::Test::vars(); my $docroot = $vars->{documentroot}; +# these match the SSI files with their expected results. +# the expectations are set by the current 2.1 mod_include +# implementation. my %test = ( "echo.shtml" => "echo.shtml", @@ -39,13 +45,17 @@ "errmsg1.shtml" => "errmsg", "errmsg2.shtml" => "errmsg", "errmsg3.shtml" => "errmsg", -"errmsg4.shtml" => $have_apache_2 ? "pass errmsg" : "pass", -"errmsg5.shtml" => "<!-- pass -->", +"errmsg4.shtml" => "pass errmsg", "if1.shtml" => "pass", "if2.shtml" => "pass pass", "if3.shtml" => "pass pass pass", "if4.shtml" => "pass pass", "if5.shtml" => "pass pass pass", +"if7.shtml" => "[an error occurred while processing this ". + "directive]", +"if8.shtml" => "pass", +"if9.shtml" => "pass pass", +"if10.shtml" => "pass", "big.shtml" => "hello pass pass pass hello", "newline.shtml" => "inc-two.shtml body", "inc-rfile.shtml" => "inc-extra2.shtml body inc-extra1.shtml body ". @@ -59,50 +69,86 @@ "exec/off/cmd.shtml" => "[an error occurred while processing this ". "directive]", "exec/on/cmd.shtml" => "pass", +"parse2.shtml" => '"', +"regex.shtml" => "(none) 1 (none)", +"retagged1.shtml" => ["retagged1.shtml", "retagged1"], +"retagged2.shtml" => ["----retagged2.shtml", "retagged1"], +"echo1.shtml" => ["<!-- pass undefined echo -->", "echo1" ], +"echo2.shtml" => ["<!-- pass undefined echo --> pass config ". + " echomsg pass", "echo1"], +"echo3.shtml" => ['<!--#echo var="DOCUMENT_NAME" -->', "retagged1"], +"exec/off/cgi.shtml" => "[an error occurred while processing this ". + "directive]", +"exec/on/cgi.shtml" => "perl cgi", +); + +# now, assuming 2.1 has the proper behavior across the board, +# let's adjust our expectations for other versions + +# these tests are known to be broken in 2.0 +# we'll mark them as TODO tests in the hopes +# that the 2.1 fixes will be backported + +my %todo = ( +"if6.shtml" => "[an error occurred while processing this ". + "directive]", +"if11.shtml" => "pass", "notreal.shtml" => "pass <!--", "parse1.shtml" => "-->", -"parse2.shtml" => "\"", -"if11.shtml" => "pass", -"malformed.shtml" => "[an error occurred while processing this directive] malformed.shtml" +"errmsg5.shtml" => "<!-- pass -->", +"malformed.shtml" => "[an error occurred while processing this ". + "directive] malformed.shtml", ); -#this test does not work on win32 (<!--#exec cmd="echo pass"-->) -if (WINFU) { - delete $test{'exec/on/cmd.shtml'}; -} - -# 1.3 gets slightly modified versions, since it cannot parse some files -# written for 2.x (requires spaces before end_seq) -if ($have_apache_2) { - $test{"if8.shtml"} = "pass"; - $test{"if9.shtml"} = "pass pass"; - $test{"if10.shtml"} = "pass"; +# some behaviors will never be backported, for various +# reasons. these are the 1.3 legacy tests and expectations +my %legacy_1_3 = ( +"errmsg4.shtml" => "pass", +"malformed.shtml" => "", +"if6.shtml" => "", +"if7.shtml" => "", +); - # regex captures are 2.x only - $test{"regex.shtml"} = "(none) 1 (none)"; +# 2.0 has no legacy tests at the moment +# but when it does, they will go here +my %legacy_2_0 = (); + +# ok, now that we have our hashes established, here are +# the manual tweaks +unless ($have_apache_2) { + # apache 1.3 uses different semantics for some + # of the if.*shtml tests to achieve the same results + $test{"if8a.shtml"} = delete $test{"if8.shtml"}; + $test{"if9a.shtml"} = delete $test{"if9.shtml"}; + $test{"if10a.shtml"} = delete $test{"if10.shtml"}; + + # while other tests are for entirely new behaviors + delete $test{"echo1.shtml"}; + delete $test{"echo2.shtml"}; + delete $test{"echo3.shtml"}; + delete $test{"retagged1.shtml"}; + delete $test{"retagged2.shtml"}; + delete $test{"regex.shtml"}; + + # these tests are only broken in 2.0 - + # shuffle and put them where they belong + $test{"malformed.shtml"} = delete $todo{"malformed.shtml"}; + $test{"parse1.shtml"} = delete $todo{"parse1.shtml"}; + $test{"errmsg5.shtml"} = delete $todo{"errmsg5.shtml"}; + + # ack - if6.shtml is different between 1.3, 2.0, and 2.1. + # don't count it as TODO in 1.3 + delete $todo{"if6.shtml"}; +} + +unless ($have_apache_21) { + # apache 2.0 do not support these tests + delete $test{"echo2.shtml"}; } -else { - $test{"if8a.shtml"} = "pass"; - $test{"if9a.shtml"} = "pass pass"; - $test{"if10a.shtml"} = "pass"; - - # malformed.shtml remains empty in 1.3 - $test{"malformed.shtml"} = "" -} - -my %t_test = (); -if ($have_apache_2) { - %t_test = - ( - "echo.shtml" => ['<!--#echo var="DOCUMENT_NAME" -->', "retagged1"], - "retagged1.shtml" => ["retagged1.shtml", "retagged1"], - "retagged2.shtml" => ["----retagged2.shtml", "retagged1"], - "echo1.shtml" => ["<!-- pass undefined echo -->", "echo1" ], - ); - if ($have_apache_21) { - $t_test{"echo2.shtml"} = ["<!-- pass undefined echo --> pass config ". - " echomsg pass", "echo1"]; - } + +# this test does not work on win32 (<!--#exec cmd="echo pass"-->) +if (WINFU) { + delete $test{'exec/on/cmd.shtml'}; } my @patterns = ( @@ -111,56 +157,75 @@ 'footer', ); -# -# in addition to $tests, there are 1 fsize/flastmod test, 1 GET test, -# 13 XBitHack tests, 2 exec cgi tests, 2 malformed-ssi-directive tests, -# and 14 tests that use mod_bucketeer to construct brigades for mod_include -# -my $tests = scalar(keys %test) + scalar(keys %t_test) + @patterns + 2; -plan tests => $tests + 33, todo => [scalar(keys %test) + 4], - have_module 'include'; +# with the tweaks out of the way, we can get on +# with planning the tests -Apache::TestRequest::scheme('http'); #ssl not listening on this vhost -Apache::TestRequest::module('mod_include'); #use this module's port +# first, total the number of hashed tests +# note that some legacy tests will redefine the main +# %test hash, so the total is not necessarily the sum +# of all the keys +my %tests = (); -foreach $doc (sort keys %test) { - ok t_cmp($test{$doc}, - super_chomp(GET_BODY "$dir$doc"), - "GET $dir$doc" - ); +if ($have_apache_21) { + %tests = (%test, %todo); +} +elsif ($have_apache_2) { + %tests = (%test, %todo, %legacy_2_0); +} +else { + %tests = (%test, %todo, %legacy_1_3); } -$doc = "printenv.shtml"; -ok t_cmp("200", - GET("$dir$doc")->code, - "GET $dir$doc" - ); +# now for the TODO tests +my @todo = (); +unless ($have_apache_21) { + # if 1.3 or 2.0, dynamically determine which of %test + # will end up being TODO tests. + + my $counter = 0; + foreach my $test (sort keys %tests) { + $counter++; + push @todo, $counter if $todo{$test}; + } + # flastmod/fsize comes immediately after the hashed tests + push @todo, (scalar keys %tests) + 1; +} -### MALFORMED DIRECTIVE TESTS -# also test a couple of malformed SSIs that used to cause Apache 1.3 to -# segfault -# - -# Apache 1.3 has a different parser so you get different output (ie, none) -my $expected = ($have_apache_2) - ? "[an error occurred while processing this directive]" - : ""; - -ok t_cmp("$expected", - super_chomp(GET_BODY "${dir}if6.shtml"), - "GET ${dir}if6.shtml" - ); +# in addition to %tests, there are 1 fsize/flastmod test, 1 GET test, +# 2 query string tests, 13 XBitHack tests and 14 tests that +# use mod_bucketeer to construct brigades for mod_include +plan tests => (scalar keys %tests) + @patterns + 31, + todo => [EMAIL PROTECTED], + have_module 'include'; -$expected = ($have_apache_2) - ? "[an error occurred while processing this directive]" - : ""; - -ok t_cmp("$expected", - super_chomp(GET_BODY "${dir}if7.shtml"), - "GET ${dir}if7.shtml" - ); +foreach $doc (sort keys %tests) { + # do as much from %test as we can + if (ref $tests{$doc}) { + ok t_cmp($tests{$doc}[0], + super_chomp(GET_BODY "$dir$doc", Host => $tests{$doc}[1]), + "GET $dir$doc" + ); + } + elsif ($doc =~ m/cgi/) { + if (have_cgi) { + ok t_cmp($tests{$doc}, + super_chomp(GET_BODY "$dir$doc"), + "GET $dir$doc" + ); + } + else { + skip "Skipping 'exec cgi' test; no cgi module.", 1; + } + } + else { + ok t_cmp($tests{$doc}, + super_chomp(GET_BODY "$dir$doc"), + "GET $dir$doc" + ); + } +} ### FLASTMOD/FSIZE TESTS ### marked as TODO since it's broken. @@ -184,7 +249,7 @@ my $oldloc = setlocale(&LC_TIME); POSIX::setlocale(&LC_TIME, "C"); - $expected = join ' ' => + my $expected = join ' ' => $strftime->("%A, %d-%b-%Y %H:%M:%S %Z"), $strftime->("%A, %d-%b-%Y %H:%M:%S %Z"), $strftime->("%A, %B %e, %G"), @@ -210,26 +275,28 @@ ); } -### EXEC CGI TESTS -# skipped if !have_cgi -my %execcgitest = ( -"exec/off/cgi.shtml" => - "[an error occurred while processing this directive]", -"exec/on/cgi.shtml" => - "perl cgi" -); -foreach $doc (sort keys %execcgitest) { - if (have_cgi()) { - ok t_cmp($execcgitest{$doc}, - super_chomp(GET_BODY "$dir$doc"), - "GET $dir$doc" - ); - } - else { - skip "Skipping 'exec cgi' test; no cgi module.", 1; - } +# some tests that can't be easily assimilated + +$doc = "printenv.shtml"; +ok t_cmp("200", + GET("$dir$doc")->code, + "GET $dir$doc" + ); + +### test include + query string +$res = GET "${dir}virtual.shtml"; + +ok $res->is_success; + +$str = $res->content; + +ok $str; + +for my $pat (@patterns) { + ok t_cmp(qr{$pat}, $str, "/$pat/"); } +### MOD_BUCKETEER+MOD_INCLUDE TESTS if (WINFU) { for (1..13) { skip "Skipping XBitHack tests on this platform", 1; @@ -304,44 +371,20 @@ ); } -### test include + query string -$res = GET "${dir}virtual.shtml"; - -ok $res->is_success; - -$str = $res->content; - -ok $str; - -for my $pat (@patterns) { - ok t_cmp(qr{$pat}, $str, "/$pat/"); -} - -### Simple tests for SSI(Start|End)Tags that differ from default -if ($have_apache_2) { - for (sort keys %t_test) { - ok t_cmp($t_test{$_}[0], - super_chomp(GET_BODY "$dir$_", Host => $t_test{$_}[1]), - "GET $dir$_" - ); - } -} - -### MOD_BUCKETEER+MOD_INCLUDE TESTS # we can use mod_bucketeer to create edge conditions for mod_include, since # it allows us to create bucket and brigade boundaries wherever we want if (have_module 'mod_bucketeer') { - $expected = "____ _____ _____ ___________________ </table> ". - "##################################1/8</tr> ". - "##################################2/8</tr> ". - "##################################3/8</tr> ". - "##################################4/8</tr> ". - "##################################5/8</tr> ". - "##################################6/8$docroot</tr> ". - "##################################7/8</tr> ". - "##################################8/8</tr> ". - "@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@"; + my $expected = "____ _____ _____ ___________________ </table> ". + "##################################1/8</tr> ". + "##################################2/8</tr> ". + "##################################3/8</tr> ". + "##################################4/8</tr> ". + "##################################5/8</tr> ". + "##################################6/8$docroot</tr> ". + "##################################7/8</tr> ". + "##################################8/8</tr> ". + "@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@"; $doc = "bucketeer/y.shtml"; ok t_cmp($expected, --- /dev/null 2003-01-30 05:24:37.000000000 -0500 +++ t/htdocs/modules/include/echo3.shtml 2003-12-10 00:14:49.000000000 -0500 @@ -0,0 +1 @@ +<!--#echo var="DOCUMENT_NAME" -->