I'm trying to use boost.test on a remote system with boost 1.33.1. On my pc this little example from http://www.boost.org/doc/libs/1_42_0/libs/test/doc/html/tutorials/hello-the-testing-world.html works:
#define BOOST_TEST_MODULE MyTest
#include <boost/test/included/unit_test.hpp> // I've changed here
int add( int i, int j ) { return i+j; }
BOOST_AUTO_TEST_CASE( my_test ) // <--- line 7
{
// seven ways to detect and report the same error:
BOOST_CHECK( add( 2,2 ) == 4 ); // #1 continues on error
BOOST_REQUIRE( add( 2,2 ) == 4 ); // #2 throws on error
if( add( 2,2 ) != 4 )
BOOST_ERROR( "Ouch..." ); // #3 continues on error
if( add( 2,2 ) != 4 )
BOOST_FAIL( "Ouch..." ); // #4 throws on error
if( add( 2,2 ) != 4 ) throw "Ouch..."; // #5 throws on error
BOOST_CHECK_MESSAGE( add( 2,2 ) == 4, // #6 continues on error
"add(..) result: " << add( 2,2 ) );
BOOST_CHECK_EQUAL( add( 2,2 ), 4 ); // #7 continues on error
}
but on the remote system the file unit_test.hpp doesn't exist. On my pc the file unit_test_framework.hpp is simply:
// deprecated
#include <boost/test/included/unit_test.hpp>
and it is present on the main system. So I tried to change the include to:
#include <boost/test/included/unit_test_framework.hpp>
but the compiler says:
main.cpp:7: error: expected constructor, destructor, or type conversion before ‘(’ token
what's this? How to solve it?
On Boost 1.33 use:
#include <boost/test/auto_unit_test.hpp>
in place of:
#include <boost/test/unit_test.hpp>
and also before the #include add:
#define BOOST_AUTO_TEST_MAIN
or you'll get a linker error
If your version of boost is older than 1.33, you should try renaming BOOST_AUTO_TEST_CASE to BOOST_AUTO_UNIT_TEST, and it shouldn't break compilation on newer versions of boost.
See these Boost.Test 1.33 Release Notes :
BOOST_AUTO_UNIT_TEST renamed to
BOOST_AUTO_TEST_CASE. Old name still
provided but deprecated
What's the boost version on your target platform? Are you using an old version there?
Since you are using a header only version of boost.test (you include the boost/test/included/unit_test.hpp header and not boost/test/unit_test.hpp), can't you just copy the working boost installation from your PC to the target machine and instruct your compiler to use it?
Related
I'm using Tcl library version 8.6.4 (compiled with Visual Studio 2015, 64bits) to interpret some Tcl commands from a C/C++ program.
I noticed that if I create interpreters from different threads, the second one ends up in an infinite loop:
#include "tcl.h"
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>
void runScript()
{
Tcl_Interp* pInterp = Tcl_CreateInterp();
std::string sTclPath = boost::filesystem::current_path().string() + "/../../stg/Debug/lib/tcl";
const char* setvalue = Tcl_SetVar( pInterp, "tcl_library", sTclPath.c_str(), TCL_GLOBAL_ONLY );
assert( setvalue != NULL );
int i = Tcl_Init( pInterp );
assert( i == TCL_OK );
int nTclResult = Tcl_Eval( pInterp, "puts \"Hello\"" );
assert( nTclResult == TCL_OK );
Tcl_DeleteInterp( pInterp );
}
int main( int argc, char* argv[] )
{
Tcl_FindExecutable(NULL);
runScript();
runScript();
boost::thread thrd1( runScript );
thrd1.join(); // works OK
boost::thread thrd2( runScript );
thrd2.join(); // never joins
return 1;
}
Infinite loop is here, within Tcl source code:
void
TclInitNotifier(void)
{
ThreadSpecificData *tsdPtr;
Tcl_ThreadId threadId = Tcl_GetCurrentThread();
Tcl_MutexLock(&listLock);
for (tsdPtr = firstNotifierPtr; tsdPtr && tsdPtr->threadId != threadId;
tsdPtr = tsdPtr->nextPtr) {
/* Empty loop body. */
}
// I never exit this loop because, after first thread was joined
// at some point tsdPtr == tsdPtr->nextPtr
Am I doing something wrong? Is there any special function call I'm missing?
Note: TCL_THREADS was not set while I compiled Tcl. However, I feel like I'm doing nothing wrong here. Also, adding
/* Empty loop body. */
if ( tsdPtr != NULL && tsdPtr->nextPtr == tsdPtr )
{
tsdPtr = NULL;
break;
}
within the loop apparently fixes the issue. But I'm not very confident in modifying 3rd party library source code...
After reporting a bug to Tcl team, I was asked to try again with Tcl library compiled with TCL_THREADS enabled. It fixed the issue.
TCL_THREADS was disabled because I compiled on windows using a CMake Lists.txt file I found on the web: this one was actually written for Linux and disabled thread support because it was unable to find pthread on my machine. I finally compiled Tcl libraries using the scripts provided by the Tcl team: threading is enabled by default and the infinite loop is gone!
Running the following example for _stat from MSDN compiled with Visual C++ 2015 Express using v140_xp as Platform Toolset (target Win32) runs normally on Windows 7 but not on Windows XP on several machines I tested.
// crt_stat.c
// This program uses the _stat function to
// report information about the file named crt_stat.c.
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
int main()
{
struct _stat buf;
int result;
char timebuf[26];
char* filename = "crt_stat.c"; // Absolute paths like "D:\\crt_stat.c" produce the same behaviour.
errno_t err;
// Get data associated with "crt_stat.c":
result = _stat( filename, &buf );
// Check if statistics are valid:
if ( result != 0 )
{
perror( "Problem getting information" );
switch ( errno )
{
case ENOENT:
printf( "File %s not found.\n", filename );
break;
case EINVAL:
printf( "Invalid parameter to _stat.\n" );
break;
default:
/* Should never be reached. */
printf( "Unexpected error in _stat.\n" );
}
}
else
{
// Output some of the statistics:
printf( "File size : %ld\n", buf.st_size );
printf( "Drive : %c:\n", buf.st_dev + 'A' );
err = ctime_s( timebuf, 26, &buf.st_mtime );
if ( err )
{
printf( "Invalid arguments to ctime_s." );
return 1;
}
printf( "Time modified : %s", timebuf );
}
}
Windows 7 output:
File size : 6
Drive : D:
Time modified : Tue Sep 8 10:06:57 2015
Windows XP output:
Problem getting information: Invalid argument
Invalid parameter to _stat.
And yes crt_stat.c is located in the executables directory which also is the CWD.
Is this a Bug or am I missing something?
As pointed out in the comments, it is a bug in the runtime. Right now (2015-09-09) the fix is not yet available in an update, but probably will be soon. A workaround is to use GetFileAttributesEx instead.
The bug is solved on Visual C++ Redistributable for Visual Studio 2015 Update 1
I solved the problem by installing that update form here: https://www.microsoft.com/en-us/download/details.aspx?id=49984
As the title says, I want to get all test suites or test cases (name) from a test application, ether in the console or as xml output.
Test framework is the boost test library.
Is there an option to achieve this? I did not found anything useful in the documentation.
There is simply the --list_content command line option, exactly for that purpose.
This can be done without much intrusion using a global fixture. Assuming you have a translation unit (cpp file) that contains main explicitly or auto generated, you can intercept test execution when a certain command line argument is provided. Then you can traverse the test tree using a customized visitor, which lists all available tests. Here is a small working example, which creates a test runner by compiling and linking files main_test.cpp, a.cpp and b.cpp:
main_test.cpp
#include <string>
#include <iostream>
// --- Boost Includes ---
#define BOOST_TEST_MODULE MyTestSuite
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
using namespace boost::unit_test;
struct Visitor : test_tree_visitor
{
size_t level = 0;
void visit( test_case const& test )
{
std::string indentation( level, '.' );
std::cout << indentation << test.p_name << std::endl;
}
bool test_suite_start( test_suite const& suite )
{
std::string indentation( level, '.' );
level++;
std::cout << indentation << "Suite: " << suite.p_name << std::endl;
return true;
}
void test_suite_finish( test_suite const& suite )
{
level--;
}
};
struct GlobalFixture
{
GlobalFixture( )
{
int argc = framework::master_test_suite( ).argc;
for ( int i = 0; i < argc; i++ )
{
std::string argument( framework::master_test_suite( ).argv[i] );
if ( argument == "list" )
{
Visitor visitor;
traverse_test_tree( framework::master_test_suite( ), visitor );
exit( EXIT_SUCCESS );
}
}
}
};
BOOST_GLOBAL_FIXTURE( GlobalFixture )
a.cpp
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE ( TestA )
BOOST_AUTO_TEST_CASE ( TestFoo )
{
BOOST_CHECK(true);
}
BOOST_AUTO_TEST_CASE ( TestBar )
{
BOOST_CHECK(true);
}
BOOST_AUTO_TEST_SUITE_END() // TestA
b.cpp
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE ( TestB )
BOOST_AUTO_TEST_CASE ( TestFoo )
{
BOOST_CHECK(true);
}
BOOST_AUTO_TEST_CASE ( TestBar )
{
BOOST_CHECK(true);
}
BOOST_AUTO_TEST_SUITE_END() // TestA
Invoking the runner without any arguments results in
./somelib_testrunner1
Running 4 test cases...
*** No errors detected
Passing the argument list used in the fixture defined above results in
Suite: MyTestSuite
.Suite: TestA
..TestFoo
..TestBar
.Suite: TestB
..TestFoo
..TestBar
I am afraid there is no easy way to do this without actually running the tests.
And even then the only thing coming to my mind without touching the code would be --log_level=test_suite and some sort of parsing script that finds the "Entering test suite", "Leaving test suite" and "Entering test case" messages (or parsing the xml given when you also put --log_format=XML, if you have a xml parser at hand).
But even that spoils the log with your added BOOST_TEST_MESSAGEs and of course encountered errors and warnings.
Seeing how the boost test framework is not much more than a bunch of macros, defined in the header, you could of course add the functionality yourself, probably easiest by adding another log format just listing the suites and tests, assuming you are fine with running the tests while finding the list.
I am trying to identify the source of an Microsoft C++ exception:
First-chance exception at 0x770ab9bc in test_fft.exe: Microsoft C++ exception: cudaError_enum at memory location 0x016cf234...
My build environment is:
IDE: Microsoft Visual C++ 2010 Express
NVIDIA Driver: 301.27
CUDA: NVIDIA CUDA Toolkit v4.2 (32-bit)
SDK: NVIDIA GPU Computing SDK 4.2 (32-bit)
Problem scope: I am trying to wrap the CUFFT behind a C++ class. This way I can hide the translation from one data type to the cufftComplex, execution of the FFT and memory transfers from the calling code.
Class header:
#ifndef SIGNAL_PROCESSING_FFT_HPP
#define SIGNAL_PROCESSING_FFT_HPP
#include "signal_processing\types.hpp"
#include <boost/cstdint.hpp>
#include <cufft.h>
#include <vector>
namespace signal_processing {
class FFT {
public:
FFT ( boost::uint32_t size );
virtual ~FFT();
void forward ( ComplexVectorT const& input, ComplexVectorT& output );
void reverse ( ComplexVectorT const& input, ComplexVectorT& output );
private:
cufftComplex* m_device_data;
cufftComplex* m_host_data;
cufftHandle m_plan;
boost::uint32_t m_size;
};
}
#endif // SIGNAL_PROCESSING_FFT_HPP
FFT constructor:
FFT::FFT ( boost::uint32_t size )
: m_size ( size )
{
CudaSafeCall ( cudaMalloc((void**)&m_device_data, sizeof(cufftComplex) * m_size ) );
m_host_data = (cufftComplex*) malloc ( m_size * sizeof(cufftComplex) );
CufftSafeCall ( cufftPlan1d ( &m_plan, m_size, CUFFT_C2C, 1 ) );
}
The Microsoft C++ exception is being thrown in the FFT constructor at the first line where the call to cudaMalloc. This error only seems to occur if I run the code using the FFT class with the Visual Studio debugger.
References
CudaSafeCall definition
#define CudaSafeCall(err) __cudaSafeCall ( err, __FILE__, __LINE__ )
__cudaSafeCall definition
inline void __cudaSafeCall ( cudaError err, const char* file, const int line )
{
#ifdef CUDA_ERROR_CHECK
if ( cudaSuccess != err )
{
std::cerr << boost::format ( "cudaSafeCall() failed at %1$s:%2$i : %3$s\n" )
% file
% line
% cudaGetErrorString ( err );
exit(-1);
}
#endif
return;
}
The observation you are making has to do with an exception that is caught and handled properly within the CUDA libraries. It is, in some cases, a normal part of CUDA GPU operation. I believe your application is returning no API errors in this case. If you were not within the VS environment that can report this, you would not observe this at all.
This is considered normal behavior under CUDA. I believe there were some attempts to eliminate it in CUDA 5.5. You might wish to try that, although it's not considered an issue either way.
Why this (copied from boost site ) gives me an error?! in VS 2010 Ultimate:
#include <boost\test\unit_test.hpp>
#define BOOST_TEST_MODULE MyTest
int add( int i, int j ) { return i+j; }
BOOST_AUTO_TEST_CASE( my_test )
{
// seven ways to detect and report the same error:
BOOST_CHECK( add( 2,2 ) == 4 ); // #1 continues on error
BOOST_REQUIRE( add( 2,2 ) == 4 ); // #2 throws on error
if( add( 2,2 ) != 4 )
BOOST_ERROR( "Ouch..." ); // #3 continues on error
if( add( 2,2 ) != 4 )
BOOST_FAIL( "Ouch..." ); // #4 throws on error
if( add( 2,2 ) != 4 ) throw "Ouch..."; // #5 throws on error
BOOST_CHECK_MESSAGE( add( 2,2 ) == 4, // #6 continues on error
"add(..) result: " << add( 2,2 ) );
BOOST_CHECK_EQUAL( add( 2,2 ), 4 ); // #7 continues on error
}
Error
Error 1 error LNK2019: unresolved external symbol "class boost::unit_test::test_suite * __cdecl init_unit_test_suite(int,char * * const)" (?init_unit_test_suite##YAPAVtest_suite#unit_test#boost##HQAPAD#Z) referenced in function _main
Try defining BOOST_TEST_MODULE before you include the header.