root/wiki-toolkit/trunk/lib/Wiki/Toolkit/TestLib.pm @ 427

Revision 427, 9.7 KB (checked in by dom, 5 years ago)

Fix test suite's incorrect passing of DBIxFTSMySQL connection parameters

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1package Wiki::Toolkit::TestLib;
2
3use strict;
4use Carp "croak";
5use Wiki::Toolkit;
6use Wiki::Toolkit::TestConfig;
7
8use vars qw( $VERSION @wiki_info );
9$VERSION = '0.03';
10
11=head1 NAME
12
13Wiki::Toolkit::TestLib - Utilities for writing Wiki::Toolkit tests.
14
15=head1 DESCRIPTION
16
17When 'perl Makefile.PL' is run on a Wiki::Toolkit distribution,
18information will be gathered about test databases etc that can be used
19for running tests. Wiki::Toolkit::TestLib gives convenient access to this
20information.
21
22=head1 SYNOPSIS
23
24  use strict;
25  use Wiki::Toolkit::TestLib;
26  use Test::More;
27
28  my $iterator = Wiki::Toolkit::TestLib->new_wiki_maker;
29  plan tests => ( $iterator->number * 6 );
30
31  while ( my $wiki = $iterator->new_wiki ) {
32      # put some test data in
33      # run six tests
34  }
35
36Each time you call C<< ->next >> on your iterator, you will get a
37fresh blank wiki object. The iterator will iterate over all configured
38search and storage backends.
39
40=cut
41
42my %configured = %Wiki::Toolkit::TestConfig::config;
43
44my %datastore_info;
45foreach my $dbtype (qw( MySQL Pg SQLite )) {
46    if ( $configured{$dbtype}{dbname} ) {
47        my %config = %{ $configured{$dbtype} };
48        my $store_class = "Wiki::Toolkit::Store::$dbtype";
49        my $setup_class = "Wiki::Toolkit::Setup::$dbtype";
50        $datastore_info{$dbtype} = {
51                                     class  => $store_class,
52                                     setup_class => $setup_class,
53                                     params => {
54                                                 dbname => $config{dbname},
55                                                 dbuser => $config{dbuser},
56                                                 dbpass => $config{dbpass},
57                                                 dbhost => $config{dbhost},
58                                               },
59                                   };
60    }
61}
62
63my %dbixfts_info;
64# DBIxFTS only works with MySQL.
65if ( $configured{dbixfts} && $configured{MySQL}{dbname} ) {
66    my %config = %{ $configured{MySQL} };
67    $dbixfts_info{MySQL} = {
68                             db_params => {
69                                            dbname => $config{dbname},
70                                            dbuser => $config{dbuser},
71                                            dbpass => $config{dbpass},
72                                            dbhost => $config{dbhost},
73                                          },
74                           };
75}
76
77my %sii_info;
78# Test the MySQL SII backend, if we can.
79if ( $configured{search_invertedindex} && $configured{MySQL}{dbname} ) {
80    my %config = %{ $configured{MySQL} };
81    $sii_info{MySQL} = {
82                         db_class  => "Search::InvertedIndex::DB::Mysql",
83                         db_params => {
84                                        -db_name    => $config{dbname},
85                                        -username   => $config{dbuser},
86                                        -password   => $config{dbpass},
87                                        -hostname   => $config{dbhost} || "",
88                                        -table_name => 'siindex',
89                                        -lock_mode  => 'EX',
90                                      },
91                       };
92}
93
94# Test the Pg SII backend, if we can.  It's not in the main S::II package.
95eval { require Search::InvertedIndex::DB::Pg; };
96my $sii_pg = $@ ? 0 : 1;
97if (    $configured{search_invertedindex}
98     && $configured{Pg}{dbname}
99     && $sii_pg
100   ) {
101    my %config = %{ $configured{Pg} };
102    $sii_info{Pg} = {
103                      db_class  => "Search::InvertedIndex::DB::Pg",
104                      db_params => {
105                                     -db_name    => $config{dbname},
106                                     -username   => $config{dbuser},
107                                     -password   => $config{dbpass},
108                                     -hostname   => $config{dbhost},
109                                     -table_name => 'siindex',
110                                     -lock_mode  => 'EX',
111                                   },
112                    };
113}
114
115# Also test the default DB_File backend, if we have S::II installed at all.
116if ( $configured{search_invertedindex} ) {
117    $sii_info{DB_File} = {
118                  db_class  => "Search::InvertedIndex::DB::DB_File_SplitHash",
119                  db_params => {
120                                 -map_name  => 't/sii-db-file-test.db',
121                                 -lock_mode  => 'EX',
122                               },
123                         };
124}
125
126my $plucene_path;
127# Test with Plucene if possible.
128if ( $configured{plucene} ) {
129    $plucene_path = "t/plucene";
130}
131
132# @wiki_info describes which searches work with which stores.
133
134# Database-specific searchers.
135push @wiki_info, { datastore_info => $datastore_info{MySQL},
136                   dbixfts_info   => $dbixfts_info{MySQL} }
137  if ( $datastore_info{MySQL} and $dbixfts_info{MySQL} );
138push @wiki_info, { datastore_info => $datastore_info{MySQL},
139                   sii_info       => $sii_info{MySQL} }
140  if ( $datastore_info{MySQL} and $sii_info{MySQL} );
141push @wiki_info, { datastore_info => $datastore_info{Pg},
142                   sii_info       => $sii_info{Pg} }
143  if ( $datastore_info{Pg} and $sii_info{Pg} );
144
145# All stores are compatible with the default S::II search, and with Plucene,
146# and with no search.
147foreach my $dbtype ( qw( MySQL Pg SQLite ) ) {
148    push @wiki_info, { datastore_info => $datastore_info{$dbtype},
149                       sii_info       => $sii_info{DB_File} }
150      if ( $datastore_info{$dbtype} and $sii_info{DB_File} );
151    push @wiki_info, { datastore_info => $datastore_info{$dbtype},
152                       plucene_path   => $plucene_path }
153      if ( $datastore_info{$dbtype} and $plucene_path );
154    push @wiki_info, { datastore_info => $datastore_info{$dbtype} }
155      if $datastore_info{$dbtype};
156}
157
158=head1 METHODS
159
160=over 4
161
162=item B<new_wiki_maker>
163
164  my $iterator = Wiki::Toolkit::TestLib->new_wiki_maker;
165
166=cut
167
168sub new_wiki_maker {
169    my $class = shift;
170    my $count = 0;
171    my $iterator = \$count;
172    bless $iterator, $class;
173    return $iterator;
174}
175
176=item B<number>
177
178  use Test::More;
179  my $iterator = Wiki::Toolkit::TestLib->new_wiki_maker;
180  plan tests => ( $iterator->number * 6 );
181
182Returns the number of new wikis that your iterator will be able to give you.
183
184=cut
185
186sub number {
187    return scalar @wiki_info;
188}
189
190=item B<new_wiki>
191
192  my $wiki = $iterator->new_wiki;
193
194Returns a fresh blank wiki object, or false if you've used up all the
195configured search and storage backends.
196
197=cut
198
199sub new_wiki {
200    my $self = shift;
201    return undef if $$self > $#wiki_info;
202    my $details = $wiki_info[$$self];
203    my %wiki_config;
204
205    # Set up and clear datastore.
206    my %datastore_info = %{ $details->{datastore_info } };
207    my $setup_class =  $datastore_info{setup_class};
208    eval "require $setup_class";
209    {
210      no strict "refs";
211      &{"$setup_class\:\:cleardb"}( $datastore_info{params} );
212      &{"$setup_class\:\:setup"}( $datastore_info{params} );
213    }
214    my $class =  $datastore_info{class};
215    eval "require $class";
216    $wiki_config{store} = $class->new( %{ $datastore_info{params} } );
217
218    # Set up and clear search object (if required).
219    if ( $details->{dbixfts_info} ) {
220        my %fts_info = %{ $details->{dbixfts_info} };
221        require Wiki::Toolkit::Store::MySQL;
222        my %dbconfig = %{ $fts_info{db_params} };
223        my $dsn = Wiki::Toolkit::Store::MySQL->_dsn( $dbconfig{dbname},
224                                                 $dbconfig{dbhost}  );
225        my $dbh = DBI->connect( $dsn, $dbconfig{dbuser}, $dbconfig{dbpass},
226                       { PrintError => 0, RaiseError => 1, AutoCommit => 1 } )
227          or croak "Can't connect to $dbconfig{dbname} using $dsn: " . DBI->errstr;
228        require Wiki::Toolkit::Setup::DBIxFTSMySQL;
229        Wiki::Toolkit::Setup::DBIxFTSMySQL::setup(
230                                 @dbconfig{ qw( dbname dbuser dbpass dbhost ) }
231                                             );
232        require Wiki::Toolkit::Search::DBIxFTS;
233        $wiki_config{search} = Wiki::Toolkit::Search::DBIxFTS->new( dbh => $dbh );
234    } elsif ( $details->{sii_info} ) {
235        my %sii_info = %{ $details->{sii_info} };
236        my $db_class = $sii_info{db_class};
237        eval "use $db_class";
238        my %db_params = %{ $sii_info{db_params} };
239        my $indexdb = $db_class->new( %db_params );
240        require Wiki::Toolkit::Setup::SII;
241        Wiki::Toolkit::Setup::SII::setup( indexdb => $indexdb );
242        $wiki_config{search} = Wiki::Toolkit::Search::SII->new(indexdb =>$indexdb);
243    } elsif ( $details->{plucene_path} ) {
244        require Wiki::Toolkit::Search::Plucene;
245        my $dir = $details->{plucene_path};
246        unlink <$dir/*>; # don't die if false since there may be no files
247        if ( -d $dir ) {
248            rmdir $dir or die $!;
249        }
250        mkdir $dir or die $!;
251        $wiki_config{search} = Wiki::Toolkit::Search::Plucene->new( path => $dir );
252    }
253
254    # Make a wiki.
255    my $wiki = Wiki::Toolkit->new( %wiki_config );
256    $$self++;
257    return $wiki;
258}
259
260=back
261
262=head1 SEE ALSO
263
264L<Wiki::Toolkit>
265
266=head1 AUTHOR
267
268Kake Pugh (kake@earth.li).
269
270=head1 COPYRIGHT
271
272     Copyright (C) 2003-2004 Kake Pugh.  All Rights Reserved.
273
274This module is free software; you can redistribute it and/or modify it
275under the same terms as Perl itself.
276
277=head1 CAVEATS
278
279If you have the L<Search::InvertedIndex> backend configured (see
280L<Wiki::Toolkit::Search::SII>) then your tests will raise warnings like
281
282  (in cleanup) Search::InvertedIndex::DB::Mysql::lock() -
283    testdb is not open. Can't lock.
284  at /usr/local/share/perl/5.6.1/Search/InvertedIndex.pm line 1348
285
286or
287
288  (in cleanup) Can't call method "sync" on an undefined value
289    at /usr/local/share/perl/5.6.1/Tie/DB_File/SplitHash.pm line 331
290    during global destruction.
291
292in unexpected places. I don't know whether this is a bug in me or in
293L<Search::InvertedIndex>.
294
295=cut
296
2971;
Note: See TracBrowser for help on using the browser.