5 use Test::More tests => 7;
9 use_ok( 'OpenSRF::Utils::Config' );
10 use_ok( 'UNIVERSAL::require' );
11 use_ok( 'Getopt::Long' );
12 use_ok( 'MARC::Record', '2.0.1' );
13 use_ok( 'Net::Domain' );
14 use_ok( 'Locale::Maketext::Lexicon' );
15 use_ok( 'Template::Plugin::POSIX' );
22 my ($gather, $hostname, $core_config, $tmpdir) =
23 (0, Net::Domain::hostfqdn(), '/openils/conf/opensrf_core.xml', '/tmp/');
27 'hostname=s' => \$hostname,
28 'config_file=s' => \$core_config,
29 'tempdir=s' => \$tmpdir,
32 while (my $mod = <DATA>) {
34 my @list = split / /, $mod;
40 my $version = $m->VERSION;
41 print "$m version $version\n" if ($version);
47 warn "Please install $mod\n";
48 $perloutput .= "Please install the $mod Perl module.\n";
50 warn "Please install one of the following modules: $mod\n";
51 $perloutput .= "Please install one of the following modules: $mod\n";
57 use OpenSRF::Transport::SlimJabber::Client;
58 use OpenSRF::Utils::SettingsParser;
59 use OpenSRF::Utils::SettingsClient;
63 (my $conf_dir = $core_config) =~ s#(.*)/.*#$1#;
64 OpenSRF::Utils::Config->load(config_file => $core_config);
65 my $conf = OpenSRF::Utils::Config->current;
66 my $settings_config = $conf->bootstrap->settings_config;
67 my $logfile = $conf->bootstrap->logfile;
68 (my $log_dir = $logfile) =~ s#(.*)/.*#$1#;
70 my $xmlparser = XML::LibXML->new();
71 my $confxml = $xmlparser->parse_file($core_config);
72 my $confxpc = XML::LibXML::XPathContext->new($confxml);
73 my $osrfxml = $xmlparser->parse_file($settings_config);
77 check_all_database_connections();
78 check_database_drivers();
80 print "\nChecking postgresql version\n";
81 system ("psql", "--version");
83 print "\nChecking libdbi and libdbi-drivers\n";
84 $output .= check_libdbd();
89 get_debug_info( $tmpdir, $log_dir, $conf_dir, $perloutput, $output );
92 sub check_all_database_connections {
93 print "\nChecking database connections\n";
94 # Check database connections
95 my @databases = $osrfxml->findnodes('//database');
97 # If we have no database connections, this is probably the OpenSRF version
100 my $de = "* WARNING: There are no database connections defined in " .
101 "opensrf.xml. These are defined in services such as " .
102 "open-ils.cstore and open-ils.reporter. Please ensure that " .
103 "your opensrf_core.xml and opensrf.xml configuration files " .
104 "are based on the examples shipped with Evergreen instead of " .
110 foreach my $database (@databases) {
111 if ($database->parentNode->parentNode->localname eq 'open-ils.qstore') {
114 my $db_name = $database->findvalue("./db");
116 $db_name = $database->findvalue("./name");
118 my $db_host = $database->findvalue("./host");
119 my $db_port = $database->findvalue("./port");
120 my $db_user = $database->findvalue("./user");
121 my $db_pw = $database->findvalue("./pw");
122 if (!$db_pw && $database->parentNode->parentNode->nodeName eq 'reporter') {
123 $db_pw = $database->findvalue("./password");
125 my $de = "* WARNING: Deprecated <password> element used for the " .
126 "<reporter> entry. Please use <pw> instead.\n";
133 foreach my $node ($database->findnodes("ancestor::node()")) {
134 next unless $node->nodeType == XML::LibXML::XML_ELEMENT_NODE;
135 $osrf_xpath .= "/" . $node->nodeName;
137 $output .= test_db_connect($db_name, $db_host, $db_port, $db_user, $db_pw, $osrf_xpath);
142 sub test_db_connect {
143 my ($db_name, $db_host, $db_port, $db_user, $db_pw, $osrf_xpath) = @_;
145 my $dsn = "dbi:Pg:dbname=$db_name;host=$db_host;port=$db_port";
147 my ($dbh, $encoding, $langs);
148 $dbh = DBI->connect($dsn, $db_user, $db_pw);
150 # Short-circuit if we didn't connect successfully
152 $de = "* $osrf_xpath :: Unable to connect to database $dsn, user=$db_user, password=$db_pw\n";
153 warn "* $osrf_xpath :: Unable to connect to database $dsn, user=$db_user, password=$db_pw\n";
157 # Get server encoding
158 my $sth = $dbh->prepare("SHOW server_encoding");
160 $sth->bind_col(1, \$encoding);
164 # Get list of server languages
165 $sth = $dbh->prepare("SELECT lanname FROM pg_catalog.pg_language");
167 $langs = $sth->fetchall_arrayref([0]);
171 print "* $osrf_xpath :: Successfully connected to database $dsn\n" unless ($de);
174 if ($encoding !~ m/(utf-?8|unicode)/i) {
175 $de .= "* ERROR: $osrf_xpath :: Database $dsn has encoding $encoding instead of UTF8 or UNICODE.\n";
176 warn "* ERROR: $osrf_xpath :: Database $dsn has encoding $encoding instead of UTF8 or UNICODE.\n";
178 print " * Database has the expected server encoding $encoding.\n";
181 my $result = check_db_langs($langs);
187 return ($de) ? $de : "* $osrf_xpath :: Successfully connected to database $dsn with encoding $encoding\n";
191 sub check_database_drivers {
192 print "\nChecking database drivers to ensure <driver> matches <language>\n";
193 # Check database drivers
194 # if language eq 'C', driver eq 'pgsql'
195 # if language eq 'perl', driver eq 'Pg'
196 my @drivers = $osrfxml->findnodes('//driver');
197 foreach my $driver_node (@drivers) {
200 my @driver_xpath_nodes;
201 foreach my $node ($driver_node->findnodes("ancestor::node()")) {
202 next unless $node->nodeType == XML::LibXML::XML_ELEMENT_NODE;
203 $driver_xpath .= "/" . $node->nodeName;
204 push @driver_xpath_nodes, $node->nodeName;
207 my $driver = $driver_node->findvalue("child::text()");
208 while (pop(@driver_xpath_nodes) && scalar(@driver_xpath_nodes) > 0 && !$language) {
209 $lang_xpath = "/" . join('/', @driver_xpath_nodes) . "/language";
210 my @lang_nodes = $osrfxml->findnodes($lang_xpath);
211 next unless scalar(@lang_nodes > 0);
212 $language = $lang_nodes[0]->findvalue("child::text()");
214 if ($driver eq "pgsql") {
215 if ($driver_xpath =~ m#/reporter/#) {
216 $result = "* ERROR: reporter application must use driver 'Pg', but '$driver' is defined\n";
218 } elsif ($language eq "C") {
219 $result = "* OK: $driver language is $language in $lang_xpath\n";
221 $result = "* ERROR: $driver language is $language in $lang_xpath\n";
224 } elsif ($driver eq "Pg") {
225 if ($driver_xpath =~ m#/reporter/#) {
226 $result = "* OK: $driver language is undefined for reporter base configuration\n";
227 } elsif ($language eq "perl") {
228 $result = "* OK: $driver language is $language in $lang_xpath\n";
230 $result = "* ERROR: $driver language is $language in $lang_xpath\n";
234 } elsif ($driver eq "SIP") {
235 $result = "* OK SIP from telephony section. \n";
238 $result = "* ERROR: Unknown driver $driver in $driver_xpath\n";
246 sub check_opensrf_core {
247 print "\nChecking $core_config for Evergreen services:\n";
248 my @public_services = $confxpc->findnodes("//services/service");
249 my $found_eg_service = 0;
250 foreach my $service (@public_services) {
251 if ($service->firstChild->nodeValue eq 'open-ils.auth') {
252 $found_eg_service = 1;
255 if ($found_eg_service) {
256 my $found .= "* OK: Found a public Evergreen service in $core_config\n";
260 my $err = "* WARNING: No public Evergreen services were found in " .
261 "$core_config; this means that you are probably still using " .
262 "the version that ships with OpenSRF. Please use the " .
263 "opensrf.xml.example file that ships with Evergreen.\n";
274 # Ensure the following PostgreSQL languages have been enabled
281 foreach my $lang (@$langs) {
282 my $lower = lc($$lang[0]);
283 $languages{$lower} = 1;
286 foreach my $lang (keys %languages) {
287 if (!$languages{$lang}) {
288 $errors .= " * ERROR: Language '$lang' is not enabled in the target database\n";
295 sub check_all_jabber {
296 foreach my $section (qw/opensrf gateway/) {
297 my $j_username = $confxpc->find("/config/$section/username");
298 my $j_password = $confxpc->find("/config/$section/passwd");
299 my $j_port = $confxpc->find("/config/$section/port");
300 # We should check for a domains element to catch likely upgrade errors
301 my $j_domain = $confxpc->find("/config/$section/domain");
302 check_jabber($j_username, $j_password, $j_domain, $j_port);
305 my @routers = $confxpc->findnodes("/config/routers/router");
306 foreach my $router (@routers) {
307 my $j_username = $router->findvalue("./transport/username");
308 my $j_password = $router->findvalue("./transport/password");
309 my $j_port = $router->findvalue("./transport/port");
310 # We should check for a domains element to catch likely upgrade errors
311 my $j_domain = $router->findvalue("./transport/server");
312 check_jabber($j_username, $j_password, $j_domain, $j_port);
317 my ($j_username, $j_password, $j_domain, $j_port) = @_;
318 print "\nChecking Jabber connection for user $j_username, domain $j_domain\n";
321 my $client = OpenSRF::Transport::SlimJabber::Client->new(
323 username => $j_username,
324 password => $j_password,
326 resource => 'test123'
332 unless($client->initialize()) {
333 $je = "* Unable to connect to jabber server $j_domain\n";
334 warn "* Unable to connect to jabber server $j_domain\n";
337 $je = "* Error connecting to jabber:\n" . shift() . "\n";
338 warn "* Error connecting to jabber:\n" . shift() . "\n";
341 print "* Jabber successfully connected\n" unless ($je);
342 $output .= ($je) ? $je : "* Jabber successfully connected\n";
346 print "\nChecking hostname\n";
347 my @hosts = $osrfxml->findnodes('/opensrf/hosts/*');
348 foreach my $host (@hosts) {
349 next unless $host->nodeType == XML::LibXML::XML_ELEMENT_NODE;
350 my $osrfhost = $host->nodeName;
352 if ($osrfhost ne $hostname && $osrfhost ne "localhost") {
353 $result = " * ERROR: expected hostname '$hostname', found '$osrfhost' in <hosts> section of opensrf.xml\n";
356 } elsif ($osrfhost eq "localhost") {
357 $result = " * OK: found hostname 'localhost' in <hosts> section of opensrf.xml\n";
359 $result = " * OK: found hostname '$hostname' in <hosts> section of opensrf.xml\n";
361 print $result unless $he;
368 my @location = `/sbin/ldconfig --print | grep libdbdpgsql`; # simple(ton) attempt to filter out build versions
370 # This is pretty distro-specific, but let's worry about other distros and operating systems when we get there
371 my $res = "libdbi PostgreSQL driver not found in shared library path;
372 you may need to edit /etc/ld.so.conf or add an entry to /etc/ld.so.conf.d/
373 and run 'ldconfig' as root\n";
377 if ($location[0] !~ m#/usr/local/lib/dbd/#) {
378 my $res = "libdbdpgsql.so was not found in /usr/local/libdbi/dbd/
379 We have found that system packages don't link against libdbi.so;
380 therefore, we strongly recommend compiling libdbi and libdbi-drivers from source.\n";
384 if ($results eq '') {
385 $results = " * OK - found locally installed libdbi.so and libdbdpgsql.so in shared library path\n";
392 my $temp_dir = shift; # place we can write files
393 my $log = shift; # location of the log directory
394 my $config = shift; # location of the config files
395 my $perl_test = shift; # output from the Perl prereq testing
396 my $config_test = shift; # output from the config file testing
398 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
399 my $oils_time = sprintf("%04d-%02d-%02d_%02dh-%02d-%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
401 # evil approach that requires no other Perl dependencies
403 my $oils_debug_dir = "$temp_dir/oils_$oils_time";
405 # Replace with something Perlish
406 mkdir($oils_debug_dir) or die $!;
408 # Replace with File::Copy
409 system("cp $log/*log $oils_debug_dir");
411 # Passwords will go through in the clear for now
412 system("cp $config/*xml $oils_debug_dir");
415 open(FH, ">", "$oils_debug_dir/perl_test.out") or die $!;
420 open(FH, ">", "$oils_debug_dir/xml_test.out") or die $!;
421 print FH $config_test;
424 # Tar this up - does any system not have tar?
425 system("tar czf oils_$oils_time.tar.gz oils_$oils_time");
427 # Clean up after ourselves, somewhat dangerously
428 system("rm -fr $oils_debug_dir");
430 print "Wrote your debug information to $temp_dir/oils_$oils_time.tar.gz.\n";
436 XML::LibXML::XPathContext
441 Class::DBI::AbstractSearch
444 Net::Z3950 Net::Z3950::ZOOM
452 DateTime::Format::ISO8601
453 DateTime::Format::Mail
456 JavaScript::SpiderMonkey
461 Spreadsheet::WriteExcel::Big
467 Business::CreditCard::Object
468 Net::Z3950::Simple2ZOOM