2
0
mirror of https://github.com/boostorg/test.git synced 2026-01-30 20:32:10 +00:00
Files
test/doc/components/prg_exec_monitor/index.html
Gennadiy Rozental 06e7e97366 in progress
[SVN r33093]
2006-02-23 19:29:10 +00:00

190 lines
12 KiB
HTML

<HTML>
<HEAD>
<TITLE>The Program Execution Monitor</TITLE>
<LINK rel="stylesheet" type="text/css" href="../../style/btl.css" media="screen">
<LINK rel="stylesheet" type="text/css" href="../../style/btl-print.css" media="print">
<META http-equiv="Content-Language" content="en-us">
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</HEAD>
<BODY>
<DIV class="header"> <A href="../../index.html">Boost.Test</A> &gt; <A href="../index.html">Components</A> &gt; <SPAN class="current_article">The
Program Execution Monitor</SPAN> </DIV>
<DIV class="body"> <IMG src="../../btl1.gif" width="252" height="43" alt="Boost Test logo">
<H1>Boost Test Library: The Program Execution Monitor</H1>
<P class="page-toc"> <A href="#Introduction">Introduction</A><BR>
<A href="#Usage">Usage</A><BR>
<A href="#Configuration">Configuration</A><BR>
<A href="#Implementation">Implementation</A><BR>
<A href="compilation.html">Compilation</A><BR>
<A href="#Examples">Examples and tests</A> </P>
<H2><A name="Introduction">Introduction</A></H2>
<P class="first-line-indented">The components of a C++ program may report user-detected
errors in several ways, such as via a return value or throwing an exception.
System-detected errors such as dereferencing an invalid pointer are reported
in other ways, totally operating system and compiler dependent.</P>
<P class="first-line-indented">Yet many C++ programs, both production and test,
must run in an environment where uniform reporting of errors is necessary.
For example, converting otherwise uncaught exceptions to non-zero program
return codes allows many command line, script, or batch environments to continue
processing in a controlled manner. Even some GUI environments benefit from
the unification of errors into program return codes.</P>
<P class="first-line-indented">The Boost Test Library's Program Execution Monitor
relieves users from messy error detection and reporting duties by providing
a replacement function main() which calls a user-supplied <SPAN class="new-term">cpp_main()</SPAN> function
within a monitored environment. The supplied main() then uniformly detects
and reports the occurrence of several types of errors, reducing them to a
uniform return code which is returned to the host environment.</P>
<P class="first-line-indented">Uniform error reporting is particularly useful
for programs running unattended under control of scripts or batch files.
Some operating systems pop up message boxes if an uncaught exception occurs,
and this requires operator intervention. By converting such exceptions to
non-zero program return codes, the library makes the program a better citizen.
More uniform reporting of errors isn't a benefit to some programs, particularly
programs always run by hand by a knowledgeable person. So the Program Execution
Monitor wouldn't be worth using in that environment.</P>
<P class="first-line-indented">Uniform error reporting could be also useful
in test environments such as the Boost regression tests. Be aware though
in such case it might be preferable to use the <A href="../utf/index.html">Unit Test Framework</A>,
cause they allows one to use the <A href="../test_tools/index.html">Test Tools</A> and
generate more detailed error information.</P>
<H2><A name="Usage">Usage</A></H2>
<P>Using the Program Execution Monitor, the traditional Hello World program
becomes:</P>
<PRE class="code">#<SPAN class="reserv-word">include</SPAN> &lt;<SPAN class="literal">iostream</SPAN>&gt;
#<SPAN class="reserv-word">include</SPAN> &lt;<SPAN class="literal">boost/test/included/prg_exec_monitor.hpp</SPAN>&gt;
<SPAN class="cpp-type">int</SPAN> cpp_main( <SPAN class="cpp-type">int</SPAN>, <SPAN class="cpp-type">char</SPAN>* [] ) <SPAN class="comment">// note name cpp_main, not main.</SPAN>
{
std::cout &lt;&lt; <SPAN class="literal">&quot;Hello, world\n&quot;</SPAN>;
<SPAN class="reserv-word">return</SPAN> <SPAN class="literal">0</SPAN>;
}
</PRE>
<P class="first-line-indented">It really is that simple - just change the name
of your initial function from main() to cpp_main(). Do make sure the argc
and argv parameters are specified (although you don't have to name them if
you don't use them). Now you can compile it. When the above program executes,
the output will be:</P>
<P class="test-output"> Hello, world<BR>
no errors detected </P>
<P class="first-line-indented">The Program Execution Monitor treat as errors:</P>
<UL>
<LI>Exceptions thrown from cpp_main().</LI>
<LI>Non-zero return from cpp_main().</LI>
</UL>
<P class="first-line-indented">So what if some function had thrown a runtime_error
with the message &quot;big trouble&quot; and it's not trapped by any catch
clause? Like in a following example: </P>
<PRE class="code">#<SPAN class="reserv-word">include</SPAN> &lt;<SPAN class="literal">stdexcept</SPAN>&gt;
#<SPAN class="reserv-word">include</SPAN> &lt;<SPAN class="literal">boost/test/included/prg_exec_monitor.hpp</SPAN>&gt;
<SPAN class="cpp-type">int</SPAN> foo() { <SPAN class="reserv-word">throw</SPAN> std::runtime_exception( <SPAN class="first-line-indented"><SPAN class="literal">&quot;big trouble&quot;</SPAN></SPAN> ); }
<SPAN class="cpp-type">int</SPAN> cpp_main( <SPAN class="cpp-type">int</SPAN>, <SPAN class="cpp-type">char</SPAN>* [] ) <SPAN class="comment">// note the name</SPAN>
{
foo()<SPAN class="literal"></SPAN>;
<SPAN class="reserv-word">return</SPAN> <SPAN class="literal">0</SPAN>;
}
</PRE>
<P class="first-line-indented">Then the output would look something like this:</P>
<P class="test-output"> **** exception(205): std::runtime_error: big trouble<BR>
******** errors detected; see standard output for details ********</P>
<P class="first-line-indented">Note that in both examples above we used inlined
version of the Program Execution Monitor. Alternatively we could compile
it into standalone library and link with it during program build. In this
case we usually don't need to include anything at all (see <A href="#BuildInstr">below</A> for
more details). Lets consider an example where function cpp_main() had bubbled
up a return code of 5:</P>
<PRE class="code">#<SPAN class="reserv-word">include</SPAN> &lt;<SPAN class="literal">boost/test/prg_exec_monitor.hpp</SPAN>&gt; <SPAN class="comment">// this header is optional</SPAN>
<SPAN class="cpp-type">int</SPAN> cpp_main( <SPAN class="cpp-type">int</SPAN>, <SPAN class="cpp-type">char</SPAN>* [] ) <SPAN class="comment">// note the name</SPAN>
{
<SPAN class="reserv-word">return</SPAN> 5;
}</PRE>
<P class="first-line-indented">Once we build this program and linked with prebuilt
Program Execution Monitor, the output would look something like this:</P>
<P class="test-output"> **** error return code: 5<BR>
******** errors detected; see standard output for details ********</P>
<P class="first-line-indented">The Program Execution Monitor
reports errors to both cout (details) and cerr (summary). Primary
detailed error messages appear
on standard output stream so that it is properly interlaced
with other output, thus aiding error analysis. While the final error notification
message appears on standard error stream. This increases the visibility of
error notification if standard output and error streams are directed to different
devices or files.</P>
<P class="first-line-indented"> The Program Execution Monitor's
supplied main() will return following result codes: </P>
<UL>
<LI>boost::exit_success - no errors</LI>
<LI>boost::exit_failure - non-zero and non-boost::exit_success return code
from cpp_main().</LI>
<LI>boost::exit_exception_failure - cpp_main() throw an exception.</LI>
</UL>
<H2><A name="Configuration">Configuration</A></H2>
<P class="first-line-indented">There are two aspects of the Program Execution
Monitor behavior that you can customize at runtime. Customization performed
using environment variables.</P>
<P class="indented">BOOST_TEST_CATCH_SYSTEM_ERRORS - allows to customize behavior
of the Program Execution Monitor in regards of catching system errors. For
more details about the meaning of this option see the Execution Monitor <A href="../execution_monitor/index.html#catch_system_errors">documentation</A>.
If you want to prevent the Program Execution Monitor from catching system
exception, set the value of this variable to <u>&quot;no&quot;</u>. The default
value is &quot;yes&quot;.</P>
<BR>
<P class="indented">BOOST_PRG_MON_CONFIRM - allows to avoid success confirmation
message. Some users prefer to see a confirmation message in case if program
successfully executed. While others don't like the clutter or any output
is prohibited by organization standards. To avoid the message set the value
of this variable to <u>&quot;no&quot;</u>. The default value is &quot;yes&quot;.</P>
<H2><A name="Implementation">Implementation</A></H2>
<P class="first-line-indented">To monitor execution of user supplied function
cpp_main() the Program Execution Monitor relies on the Boost Test's <A href="../execution_monitor/index.html">Execution
Monitor</A> . Also the Program Execution Monitor supply function main().
For the program to link successfully user is required to supply a function
cpp_main() with same interface as the main(). </P>
<P class="first-line-indented"><A name="BuildInstr"></A>You could use either
header-only inlined version of the Program Execution Monitor implemented
in &lt;<A href="../../../../../boost/test/included/prg_exec_monitor.hpp">boost/test/included/prg_exec_monitor.hpp</A>&gt; of <A href="compilation.html">build</A> standalone
library and link with it during program build in which case nothing needs
to be included. Bur If you wish to link with dynamic version of prebuilt
library or employ auto-lining feature available for Microsoft compilers you
need an extra support implemented in &lt;<A href="../../../../../boost/test/prg_exec_monitor.hpp">boost/test/prg_exec_monitor.hpp</A>&gt;.</P>
<P class="first-line-indented">Following files are used in
the Program Execution Monitor implementation:</P>
<H4><A href="../../../../../boost/test/execution_monitor.hpp">libs/test/execution_monitor.cpp</A>:</H4>
<P class="first-line-indented">The <A href="../execution_monitor/index.html">Execution
Monitor</A> implementation. </P>
<H4><A href="../../../../../boost/test/cpp_main.hpp">libs/test/cpp_main.cpp</A>:</H4>
<P class="first-line-indented">Supply function main() for static library build </P>
<H4><A href="../../../../../boost/test/execution_monitor.hpp">boost/test/included/prg_exec_monitor.hpp</A>:</H4>
<P class="first-line-indented">Combine all implementation files into single
header to be use as inlined version of component </P>
<H4><A href="../../../../../boost/test/execution_monitor.hpp">boost/test/prg_exec_monitor.hpp</A>:</H4>
<P class="first-line-indented">Contains definitions for main() function for
dynamic library build and pragmas for auto-linking feature support. </P>
<H2><A name="Examples">Examples and tests</A></H2>
<P class ="indented"> <A href="../../examples/prog_exec_monitor_example.html">prg_exec_example</A><BR>
<A href="../../tests/prg_exec_fail1.html">prg_exec_fail1</A><BR>
<A href="../../tests/prg_exec_fail2.html">prg_exec_fail2</A><BR>
<A href="../../tests/prg_exec_fail3.html">prg_exec_fail3</A><BR>
<A href="../../tests/prg_exec_fail4.html">prg_exec_fail4</A><BR>
</DIV>
<DIV class="footer">
<DIV class="footer-body">
<P> &copy; <A name="Copyright">Copyright</A> <A href="mailto:boost-test%20at%20emailaccount%20dot%20com%20%28please%20unobscure%29">Gennadiy
Rozental</A> 2001-2006. <BR>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file <A href="../../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy
at <A href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</A>)</P>
<P>Revised:
<!-- #BeginDate format:Sw1 -->18 February, 2006<!-- #EndDate -->
</P>
</DIV>
</DIV>
</BODY>
</HTML>