Commit a86e015d authored by Stephen Morris's avatar Stephen Morris
Browse files

[trac976] Add additional tests for different destinations

parent 92113f50
......@@ -891,6 +891,7 @@ AC_OUTPUT([doc/version.ent
src/lib/cc/session_config.h.pre
src/lib/cc/tests/session_unittests_config.h
src/lib/log/tests/console_test.sh
src/lib/log/tests/destination_test.sh
src/lib/log/tests/local_file_test.sh
src/lib/log/tests/severity_test.sh
src/lib/log/tests/tempdir.h
......@@ -922,6 +923,7 @@ AC_OUTPUT([doc/version.ent
chmod +x src/lib/dns/tests/testdata/gen-wiredata.py
chmod +x src/lib/log/tests/local_file_test.sh
chmod +x src/lib/log/tests/console_test.sh
chmod +x src/lib/log/tests/destination_test.sh
chmod +x src/lib/log/tests/severity_test.sh
chmod +x src/lib/util/python/mkpywrapper.py
chmod +x tests/system/conf.sh
......
......@@ -56,5 +56,6 @@ noinst_PROGRAMS = $(TESTS)
PYTESTS = console_test.sh local_file_test.sh severity_test.sh
check-local:
$(SHELL) $(abs_builddir)/console_test.sh
$(SHELL) $(abs_builddir)/destination_test.sh
$(SHELL) $(abs_builddir)/local_file_test.sh
$(SHELL) $(abs_builddir)/severity_test.sh
......@@ -37,22 +37,22 @@ passfail() {
echo "1. Checking that console output to stdout goes to stdout:"
rm -f $tempfile
./logger_example -c stdout -s error -c stdout 1> $tempfile
passfail 2
./logger_example -c stdout -s error 1> $tempfile
passfail 4
echo "2. Checking that console output to stdout does not go to stderr:"
rm -f $tempfile
./logger_example -c stdout -s error -c stdout 2> $tempfile
./logger_example -c stdout -s error 2> $tempfile
passfail 0
echo "3. Checking that console output to stderr goes to stderr:"
rm -f $tempfile
./logger_example -c stdout -s error -c stderr 2> $tempfile
passfail 2
./logger_example -c stderr -s error 2> $tempfile
passfail 4
echo "4. Checking that console output to stderr does not go to stdout:"
rm -f $tempfile
./logger_example -c stdout -s error -c stderr 1> $tempfile
./logger_example -c stderr -s error 1> $tempfile
passfail 0
rm -f $tempfile
......
#!/bin/sh
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# \brief Severity test
#
# Checks that the logger will limit the output of messages less severy than
# the severity/debug setting.
testname="Destination test"
echo $testname
failcount=0
tempfile=@abs_builddir@/destination_test_tempfile_$$
destfile1=@abs_builddir@/destination_test_destfile_1_$$
destfile2=@abs_builddir@/destination_test_destfile_2_$$
passfail() {
if [ $1 -eq 0 ]; then
echo " -- pass"
else
echo " ** FAIL"
failcount=`expr $failcount + $1`
fi
}
echo "1. One logger, multiple destinations"
cat > $tempfile << .
FATAL [example] MSG_WRITERR, error writing to test1: 42
ERROR [example] MSG_RDLOCMES, reading local message file dummy/file
FATAL [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta_fatal
ERROR [example.beta] MSG_BADDESTINATION, unrecognized log destination: beta_error
.
rm -f $destfile1 $destfile2
./logger_example -s error -f $destfile1 -f $destfile2
cut -d' ' -f3- $destfile1 | diff $tempfile -
passfail $?
cut -d' ' -f3- $destfile2 | diff $tempfile -
passfail $?
echo "2. Two loggers, different destinations and severities"
rm -f $destfile1 $destfile2
./logger_example -l example -s info -f $destfile1 -l alpha -s warn -f $destfile2
# All output for example and example.beta should have gone to destfile1.
# Output for example.alpha should have done to destfile2.
cat > $tempfile << .
FATAL [example] MSG_WRITERR, error writing to test1: 42
ERROR [example] MSG_RDLOCMES, reading local message file dummy/file
WARN [example] MSG_BADSTREAM, bad log console output stream: example
FATAL [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta_fatal
ERROR [example.beta] MSG_BADDESTINATION, unrecognized log destination: beta_error
WARN [example.beta] MSG_BADSTREAM, bad log console output stream: beta_warn
INFO [example.beta] MSG_READERR, error reading from message file beta: info
.
cut -d' ' -f3- $destfile1 | diff $tempfile -
passfail $?
cat > $tempfile << .
WARN [example.alpha] MSG_READERR, error reading from message file a.txt: dummy reason
.
cut -d' ' -f3- $destfile2 | diff $tempfile -
passfail $?
if [ $failcount -eq 0 ]; then
echo "PASS: $testname"
elif [ $failcount -eq 1 ]; then
echo "FAIL: $testname - 1 test failed"
else
echo "FAIL: $testname - $failcount tests failed"
fi
exit $failcount
......@@ -45,20 +45,28 @@ cat > $localmes << .
echo "1. Local message replacement:"
cat > $tempfile << .
WARN [alpha.log] MSG_IDNOTFND, could not replace message text for 'MSG_NOTHERE': no such message
FATAL [alpha.example] MSG_WRITERR, error writing to test1: 42
ERROR [alpha.example] MSG_RDLOCMES, replacement read local message file, parameter is 'dummy/file'
WARN [alpha.dlm] MSG_READERR, replacement read error, parameters: 'a.txt' and 'dummy reason'
WARN [example.log] MSG_IDNOTFND, could not replace message text for 'MSG_NOTHERE': no such message
FATAL [example] MSG_WRITERR, error writing to test1: 42
ERROR [example] MSG_RDLOCMES, replacement read local message file, parameter is 'dummy/file'
WARN [example] MSG_BADSTREAM, bad log console output stream: example
WARN [example.alpha] MSG_READERR, replacement read error, parameters: 'a.txt' and 'dummy reason'
FATAL [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta_fatal
ERROR [example.beta] MSG_BADDESTINATION, unrecognized log destination: beta_error
WARN [example.beta] MSG_BADSTREAM, bad log console output stream: beta_warn
.
./logger_example -c stdout -s warn $localmes | cut -d' ' -f3- | diff $tempfile -
passfail $?
echo "2. Report error if unable to read local message file:"
cat > $tempfile << .
ERROR [alpha.log] MSG_OPENIN, unable to open message file $localmes for input: No such file or directory
FATAL [alpha.example] MSG_WRITERR, error writing to test1: 42
ERROR [alpha.example] MSG_RDLOCMES, reading local message file dummy/file
WARN [alpha.dlm] MSG_READERR, error reading from message file a.txt: dummy reason
ERROR [example.log] MSG_OPENIN, unable to open message file $localmes for input: No such file or directory
FATAL [example] MSG_WRITERR, error writing to test1: 42
ERROR [example] MSG_RDLOCMES, reading local message file dummy/file
WARN [example] MSG_BADSTREAM, bad log console output stream: example
WARN [example.alpha] MSG_READERR, error reading from message file a.txt: dummy reason
FATAL [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta_fatal
ERROR [example.beta] MSG_BADDESTINATION, unrecognized log destination: beta_error
WARN [example.beta] MSG_BADSTREAM, bad log console output stream: beta_warn
.
rm -f $localmes
./logger_example -c stdout -s warn $localmes | cut -d' ' -f3- | diff $tempfile -
......
......@@ -28,6 +28,7 @@
#include <iostream>
#include <string>
#include <vector>
#include <util/strutil.h>
......@@ -49,23 +50,54 @@ using namespace std;
void usage() {
cout <<
"logger_support_test [-h] [-c stream] [-d dbglevel] [-f file]\n"
" [-s severity] [localfile]\n"
"logger_support_test [-h | [logger_spec] [[logger_spec]...]]\n"
"\n"
" -h Print this message and exit\n"
" -h Print this message and exit\n"
"\n"
"The rest of the command line comprises the set of logger specifications.\n"
"Each specification is of the form:\n"
"\n"
" -l logger [-s severity] [-d dbglevel] output_spec] [[output_spec] ...\n"
"\n"
"where:\n"
"\n"
" -l logger Give the name of the logger to which the following\n"
" output specifications will apply.\n"
"\n"
"Each logger is followed by the indication of the serverity it is logging\n"
"and, if applicable, its debug level:\n"
"\n"
" -d dbglevel Debug level. Only interpreted if the severity is 'debug'\n"
" this is a number between 0 and 99.\n"
" -c stream Send output to the console. 'stream' is one of 'stdout'\n"
" of 'stderr'. The '-c' switch is incompatible with '-f'\n"
" and '-l'\n"
" -f file Send output to specified file, appending to existing file\n"
" if one exists. Incompatible with -c and -l switches.\n"
" -s severity Set the severity of messages output. 'severity' is one\n"
" of 'debug', 'info', 'warn', 'error', 'fatal', the default\n"
" being 'info'.\n"
"\n"
"If none of -c, -f or -l is given, by default, output is sent to stdout\n";
"The output specifications - there may be more than one per logger - detail\n"
"the output streams attached to the logger. These are of the form:\n"
"\n"
" -c stream | -f file [-m maxver] [-z maxsize] | -y facility\n"
"\n"
"These are:\n"
"\n"
" -c stream Send output to the console. 'stream' is one of 'stdout'\n"
" of 'stderr'.\n"
" -f file Send output to specified file, appending to existing file\n"
" if one exists.\n"
" -y facility Send output to the syslog file with the given facility\n"
" name (e.g. local1, cron etc.)\n"
"\n"
"The following can be specified for the file logger:\n"
"\n"
" -m maxver If file rolling is selected (by the maximum file size being\n"
" non-zero), the maximum number of versions to keep (defaults\n"
" to 0)\n"
" -z maxsize Maximum size of the file before the file is closed and a\n"
" new one opened. The default of 0 means no maximum size.\n"
"\n"
"If none of -c, -f or -y is given, by default, output is sent to stdout. If no\n"
"logger is specified, the default is the program's root logger ('example').\n";
}
......@@ -73,37 +105,57 @@ void usage() {
// messages. Looking at the output determines whether the program worked.
int main(int argc, char** argv) {
const string ROOT_NAME = "alpha";
const string ROOT_NAME = "example";
bool sw_found = false; // Set true if switch found
bool c_found = false; // Set true if "-c" found
bool f_found = false; // Set true if "-f" found
bool l_found = false; // Set true if "-l" found
bool y_found = false; // Set true if "-y" found
int option; // For getopt() processing
LoggerSpecification spec(ROOT_NAME); // Logger specification
OutputOption outopt; // Logger output option
// Initialize loggers (to set the root name and initialize logging);
LoggerManager::init(ROOT_NAME);
// Parse options
while ((option = getopt(argc, argv, "hc:d:f:s:")) != -1) {
OutputOption def_opt; // Default output option - used
// for initialization
LoggerSpecification cur_spec(ROOT_NAME);// Current specification
OutputOption cur_opt; // Current output option
vector<LoggerSpecification> loggers; // Set of logger specifications
vector<OutputOption> options; // Output options for logger
std::string severity; // Severity set for logger
// Initialize logging system - set the root logger name.
LoggerManager manager;
manager.init(ROOT_NAME);
// In the parsing loop that follows, the construction of the logging
// specification is always "one behind". In other words, the parsing of
// command-line options updates thge current logging specification/output
// options. When the flag indicating a new logger or output specification
// is encountered, the previous one is added to the list.
//
// One complication is that there is deemed to be a default active when
// the parsing starts (console output for the BIND 10 root logger). This
// is included in the logging specifications UNLESS the first switch on
// the command line is a "-l" flag starting a new logger. To track this,
// the "sw_found" flag is set when a switch is completey processed. The
// processing of "-l" will only add information for a previous logger to
// the list if this flag is set.
while ((option = getopt(argc, argv, "hc:d:f:l:m:s:y:z:")) != -1) {
switch (option) {
case 'c':
if (f_found || l_found) {
cerr << "Cannot specify -c with -f or -l\n";
return (1);
case 'c': // Console output
// New output spec. If one was currently active, add it to the
// list and reset the current output option to the defaults.
if (c_found || f_found || y_found) {
cur_spec.addOutputOption(cur_opt);
cur_opt = def_opt;
c_found = f_found = y_found = false;
}
// Set the output option for this switch.
c_found = true;
outopt.destination = OutputOption::DEST_CONSOLE;
cur_opt.destination = OutputOption::DEST_CONSOLE;
if (strcmp(optarg, "stdout") == 0) {
outopt.stream = OutputOption::STR_STDOUT;
cur_opt.stream = OutputOption::STR_STDOUT;
} else if (strcmp(optarg, "stderr") == 0) {
outopt.stream = OutputOption::STR_STDERR;
cur_opt.stream = OutputOption::STR_STDERR;
} else {
cerr << "Unrecognised console option: " << optarg << "\n";
......@@ -111,66 +163,143 @@ int main(int argc, char** argv) {
}
break;
case 'd':
spec.setDbglevel(boost::lexical_cast<int>(optarg));
case 'd': // Debug level
cur_spec.setDbglevel(boost::lexical_cast<int>(optarg));
break;
case 'f':
if (c_found || l_found) {
cerr << "Cannot specify -f with -c or -l\n";
return (1);
case 'f': // File output specification
// New output spec. If one was currently active, add it to the
// list and reset the current output option to the defaults.
if (c_found || f_found || y_found) {
cur_spec.addOutputOption(cur_opt);
cur_opt = def_opt;
c_found = f_found = y_found = false;
}
// Set the output option for this switch.
f_found = true;
outopt.destination = OutputOption::DEST_FILE;
outopt.filename = optarg;
cur_opt.destination = OutputOption::DEST_FILE;
cur_opt.filename = optarg;
break;
case 'h':
case 'h': // Help
usage();
return (0);
case 's':
{
string severity(optarg);
isc::util::str::uppercase(severity);
spec.setSeverity(getSeverity(severity));
case 'l': // Logger
// If a current specification is active, add the last output option
// to it, add it to the list and reset. A specification is active
// if at least one switch has been previously found.
if (sw_found) {
cur_spec.addOutputOption(cur_opt);
loggers.push_back(cur_spec);
cur_spec.reset();
}
// Set the logger name
cur_spec.setName(std::string(optarg));
// Reset the output option to the default.
cur_opt = def_opt;
// Indicate nothing is found to prevent the console option (the
// default output option) being added to the output list if an
// output option is found.
c_found = f_found = y_found = false;
break;
case 'm': // Maximum file version
if (!f_found) {
std::cerr << "Attempt to set maximum version (-m) "
"outside of file output specification\n";
return (1);
}
try {
cur_opt.maxsize = boost::lexical_cast<unsigned int>(optarg);
} catch (boost::bad_lexical_cast&) {
std::cerr << "Maximum version (-m) argument must be a positive "
"integer\n";
return (1);
}
break;
case 's': // Severity
severity = optarg;
isc::util::str::uppercase(severity);
cur_spec.setSeverity(getSeverity(severity));
break;
case 'y': // Syslog output
// New output spec. If one was currently active, add it to the
// list and reset the current output option to the defaults.
if (c_found || f_found || y_found) {
cur_spec.addOutputOption(cur_opt);
cur_opt = def_opt;
c_found = f_found = y_found = false;
}
y_found = true;
cur_opt.destination = OutputOption::DEST_SYSLOG;
cur_opt.facility = optarg;
break;
case 'z': // Maximum size
if (! f_found) {
std::cerr << "Attempt to set file size (-z) "
"outside of file output specification\n";
return (1);
}
try {
cur_opt.maxsize = boost::lexical_cast<size_t>(optarg);
} catch (boost::bad_lexical_cast&) {
std::cerr << "File size (-z) argument must be a positive "
"integer\n";
return (1);
}
break;
default:
std::cerr << "Unrecognised option: " <<
static_cast<char>(option) << "\n";
return (1);
}
// Have found at least one command-line switch, so note the fact.
sw_found = true;
}
// Update the logging parameters. If no output options
// were set, the defaults will be used.
spec.addOutputOption(outopt);
// Add the current (unfinished specification) to the list.
cur_spec.addOutputOption(cur_opt);
loggers.push_back(cur_spec);
// Set the logging options for the root logger.
LoggerManager manager;
manager.process(spec);
// Set the logging options.
manager.process(loggers.begin(), loggers.end());
// Set the local file
if (optind < argc) {
LoggerManager::readLocalMessageFile(argv[optind]);
}
// Log a few messages to different loggers.
isc::log::Logger logger_ex(ROOT_NAME);
isc::log::Logger logger_alpha("alpha");
isc::log::Logger logger_beta("beta");
// Log a few messages
isc::log::Logger logger_dlm("dlm");
isc::log::Logger logger_ex("example");
LOG_FATAL(logger_ex, MSG_WRITERR).arg("test1").arg("42");
LOG_ERROR(logger_ex, MSG_RDLOCMES).arg("dummy/file");
LOG_WARN(logger_dlm, MSG_READERR).arg("a.txt").arg("dummy reason");
LOG_INFO(logger_dlm, MSG_OPENIN).arg("example.msg").arg("dummy reason");
LOG_DEBUG(logger_ex, 0, MSG_RDLOCMES).arg("dummy/0");
LOG_DEBUG(logger_ex, 24, MSG_RDLOCMES).arg("dummy/24");
LOG_DEBUG(logger_ex, 25, MSG_RDLOCMES).arg("dummy/25");
LOG_DEBUG(logger_ex, 26, MSG_RDLOCMES).arg("dummy/26");
LOG_WARN(logger_ex, MSG_BADSTREAM).arg("example");
LOG_WARN(logger_alpha, MSG_READERR).arg("a.txt").arg("dummy reason");
LOG_INFO(logger_alpha, MSG_OPENIN).arg("example.msg").arg("dummy reason");
LOG_DEBUG(logger_ex, 0, MSG_RDLOCMES).arg("example/0");
LOG_DEBUG(logger_ex, 24, MSG_RDLOCMES).arg("example/24");
LOG_DEBUG(logger_ex, 25, MSG_RDLOCMES).arg("example/25");
LOG_DEBUG(logger_ex, 26, MSG_RDLOCMES).arg("example/26");
LOG_FATAL(logger_beta, MSG_BADSEVERITY).arg("beta_fatal");
LOG_ERROR(logger_beta, MSG_BADDESTINATION).arg("beta_error");
LOG_WARN(logger_beta, MSG_BADSTREAM).arg("beta_warn");
LOG_INFO(logger_beta, MSG_READERR).arg("beta").arg("info");
LOG_DEBUG(logger_beta, 25, MSG_BADSEVERITY).arg("beta/25");
LOG_DEBUG(logger_beta, 26, MSG_BADSEVERITY).arg("beta/26");
return (0);
}
......@@ -35,31 +35,44 @@ passfail() {
echo "1. runInitTest default parameters: "
cat > $tempfile << .
FATAL [alpha.example] MSG_WRITERR, error writing to test1: 42
ERROR [alpha.example] MSG_RDLOCMES, reading local message file dummy/file
WARN [alpha.dlm] MSG_READERR, error reading from message file a.txt: dummy reason
INFO [alpha.dlm] MSG_OPENIN, unable to open message file example.msg for input: dummy reason
FATAL [example] MSG_WRITERR, error writing to test1: 42
ERROR [example] MSG_RDLOCMES, reading local message file dummy/file
WARN [example] MSG_BADSTREAM, bad log console output stream: example
WARN [example.alpha] MSG_READERR, error reading from message file a.txt: dummy reason
INFO [example.alpha] MSG_OPENIN, unable to open message file example.msg for input: dummy reason
FATAL [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta_fatal
ERROR [example.beta] MSG_BADDESTINATION, unrecognized log destination: beta_error
WARN [example.beta] MSG_BADSTREAM, bad log console output stream: beta_warn
INFO [example.beta] MSG_READERR, error reading from message file beta: info
.
./logger_example -c stdout | cut -d' ' -f3- | diff $tempfile -
passfail $?
echo "2. Severity filter: "
cat > $tempfile << .
FATAL [alpha.example] MSG_WRITERR, error writing to test1: 42
ERROR [alpha.example] MSG_RDLOCMES, reading local message file dummy/file
FATAL [example] MSG_WRITERR, error writing to test1: 42
ERROR [example] MSG_RDLOCMES, reading local message file dummy/file
FATAL [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta_fatal
ERROR [example.beta] MSG_BADDESTINATION, unrecognized log destination: beta_error
.
./logger_example -c stdout -s error | cut -d' ' -f3- | diff $tempfile -
passfail $?
echo "3. Debug level: "
cat > $tempfile << .
FATAL [alpha.example] MSG_WRITERR, error writing to test1: 42
ERROR [alpha.example] MSG_RDLOCMES, reading local message file dummy/file
WARN [alpha.dlm] MSG_READERR, error reading from message file a.txt: dummy reason
INFO [alpha.dlm] MSG_OPENIN, unable to open message file example.msg for input: dummy reason
DEBUG [alpha.example] MSG_RDLOCMES, reading local message file dummy/0
DEBUG [alpha.example] MSG_RDLOCMES, reading local message file dummy/24
DEBUG [alpha.example] MSG_RDLOCMES, reading local message file dummy/25
FATAL [example] MSG_WRITERR, error writing to test1: 42
ERROR [example] MSG_RDLOCMES, reading local message file dummy/file
WARN [example] MSG_BADSTREAM, bad log console output stream: example
WARN [example.alpha] MSG_READERR, error reading from message file a.txt: dummy reason
INFO [example.alpha] MSG_OPENIN, unable to open message file example.msg for input: dummy reason
DEBUG [example] MSG_RDLOCMES, reading local message file example/0
DEBUG [example] MSG_RDLOCMES, reading local message file example/24
DEBUG [example] MSG_RDLOCMES, reading local message file example/25
FATAL [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta_fatal
ERROR [example.beta] MSG_BADDESTINATION, unrecognized log destination: beta_error
WARN [example.beta] MSG_BADSTREAM, bad log console output stream: beta_warn
INFO [example.beta] MSG_READERR, error reading from message file beta: info
DEBUG [example.beta] MSG_BADSEVERITY, unrecognized log severity: beta/25
.
./logger_example -c stdout -s debug -d 25 | cut -d' ' -f3- | diff $tempfile -
passfail $?
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment