use Test; use Config; use constant MAX_THREADS => 10; use constant MAX_LOOP => 50; use constant PLAN => 14; BEGIN { plan tests => PLAN; if( $Config{useithreads} ) { if ($ENV{THREAD_TEST}) { require threads;; } else { skip("optional (set THREAD_TEST=1 to run these tests)\n") for (1..PLAN); exit; } } else { skip("no ithreads in this Perl\n") for (1..PLAN); exit; } } use XML::LibXML; ok(1); my $p = XML::LibXML->new(); ok($p); # Simple spawn threads with $p in scope { for(1..MAX_THREADS) { threads->new(sub {}); } $_->join for(threads->list); ok(1); } my $xml = < EOF # Parse a correct XML document { for(1..MAX_THREADS) { threads->new(sub { $p->parse_string($xml) for 1..MAX_LOOP; 1; }); } $_->join for(threads->list); ok(1); } my $xml_bad = < EOF # Parse a bad XML document { for(1..MAX_THREADS) { threads->new(sub { eval { my $x = $p->parse_string($xml_bad)} for(1..MAX_LOOP); 1; }); } $_->join for(threads->list); ok(1); } my $xml_invalid = < ]> EOF # Parse an invalid XML document { for(1..MAX_THREADS) { threads->new(sub { for (1..MAX_LOOP) { my $x = $p->parse_string($xml_invalid); die if $x->is_valid; eval { $x->validate }; die unless $@; } 1; }); } $_->join for(threads->list); ok(1); } my $rngschema = < EOF # test RNG validation errors are thread safe { for(1..MAX_THREADS) { threads->new( sub { for (1..MAX_LOOP) { my $x = $p->parse_string($xml); eval { XML::LibXML::RelaxNG->new( string => $rngschema )->validate( $x ) }; die unless $@; }; 1; }); } $_->join for(threads->list); ok(1); } my $xsdschema = < EOF # test Schema validation errors are thread safe { for(1..MAX_THREADS) { threads->new( sub { for (1..MAX_LOOP) { my $x = $p->parse_string($xml); eval { XML::LibXML::Schema->new( string => $xsdschema )->validate( $x ) }; die unless $@; }; 1; }); } $_->join for(threads->list); ok(1); } my $bigfile = "docs/libxml.dbk"; open my $fh, "<:utf8", $bigfile or die $!; $xml = join '', <$fh>; close $fh; ok($xml); sub use_dom { my $d = shift; my @nodes = $d->getElementsByTagName("title",1); for(@nodes) { my $title = $_->toString; } die unless $nodes[0]->toString eq 'XML::LibXML'; } { for(1..MAX_THREADS) { threads->new(sub { use_dom($p->parse_string($xml)) for 1..5; 1; }); } $_->join for(threads->list); ok(1); } { package MyHandler; use base XML::SAX::Base; sub AUTOLOAD { } } use XML::LibXML::SAX; $p = XML::LibXML::SAX->new( Handler=>MyHandler->new(), ); ok($p); { for(1..MAX_THREADS) { threads->new(sub { $p->parse_string($xml) for 1..10; 1; }); } $_->join for(threads->list); ok(1); } $p = XML::LibXML->new( Handler=>MyHandler->new(), ); $p->parse_chunk($xml); $p->parse_chunk("",1); { for(1..MAX_THREADS) { threads->new(sub { $p = XML::LibXML->new(); $p->parse_chunk($xml); use_dom($p->parse_chunk("",1)); 1; }); } $_->join for(threads->list); ok(1); } $p = XML::LibXML->new(); { for(1..MAX_THREADS) { threads->new(sub { open my $fh, "<$bigfile"; $p->parse_fh($fh); close $fh; 1; }); } $_->join for(threads->list); ok(1); }