/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * AtomicInstanceUnitTest.cpp * * Created on: Apr 26, 2016 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "AtomicInstanceUnitTest.hpp" #include #include #include #include #include "CodePatterns/AtomicInstance.hpp" #ifdef HAVE_TESTRUNNER #include "UnitTestMain.hpp" #endif /*HAVE_TESTRUNNER*/ CPPUNIT_TEST_SUITE_REGISTRATION( AtomicInstanceTest ); // some necessary stubs class AtomicInstanceStub1 { public: AtomicInstanceStub1(){ count1++; } // explicit copy constructor to catch if this is ever called AtomicInstanceStub1(const AtomicInstanceStub1&){ CPPUNIT_FAIL ( "Copy constructor of AtomicInstance called" ); } virtual ~AtomicInstanceStub1(){ count2++; } public: static int count1; static int count2; }; int AtomicInstanceStub1::count1 = 0; int AtomicInstanceStub1::count2 = 0; //CONSTRUCT_ATOMIC(AtomicInstanceStub1) // some necessary stubs class AtomicInstanceStub2 { public: AtomicInstanceStub2(){ count1++; } // explicit copy constructor to catch if this is ever called AtomicInstanceStub2(const AtomicInstanceStub2&){ CPPUNIT_FAIL ( "Copy constructor of AtomicInstance called" ); } virtual ~AtomicInstanceStub2(){ count2++; } public: static int count1; static int count2; }; int AtomicInstanceStub2::count1 = 0; int AtomicInstanceStub2::count2 = 0; //CONSTRUCT_ATOMIC(AtomicInstanceStub2) void AtomicInstanceTest::setUp() { ASSERT_DO(Assert::Throw); } void AtomicInstanceTest::tearDown(){} static bool checkLock(boost::mutex &_mutex) { boost::mutex::scoped_lock lock(_mutex, boost::try_to_lock); return lock; } void AtomicInstanceTest::ConstructionTest() { AtomicInstanceStub1 *ptr1_1 = new AtomicInstanceStub1(); AtomicInstanceStub2 *ptr2_1 = new AtomicInstanceStub2(); { CPPUNIT_ASSERT( checkLock(AtomicInstance::atomicLock) ); AtomicInstance atomic_ptr1_1(ptr1_1); CPPUNIT_ASSERT_EQUAL( ptr1_1, &(*atomic_ptr1_1) ); CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); // will NULL no deadlock occurs { CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); AtomicInstance atomic_ptr1_NULL(NULL); CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); } CPPUNIT_ASSERT( checkLock(AtomicInstance::atomicLock) ); const AtomicInstance atomic_ptr2_1(ptr2_1); CPPUNIT_ASSERT_EQUAL( const_cast(ptr2_1), &(*atomic_ptr2_1) ); CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); // move is ok CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); AtomicInstance atomic_ptr1_2(atomic_ptr1_1); CPPUNIT_ASSERT( atomic_ptr1_1.content == (AtomicInstanceStub1 *)NULL); CPPUNIT_ASSERT( atomic_ptr1_2.content != (AtomicInstanceStub1 *)NULL); CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); // this would cause deadlock // AtomicInstance atomic_ptr1_3(ptr1_1); } CPPUNIT_ASSERT( checkLock(AtomicInstance::atomicLock) ); CPPUNIT_ASSERT( checkLock(AtomicInstance::atomicLock) ); delete ptr1_1; delete ptr2_1; } void AtomicInstanceTest::AssignmentTest() { AtomicInstanceStub1 *ptr1_1 = new AtomicInstanceStub1(); { // this does not lock CPPUNIT_ASSERT( checkLock(AtomicInstance::atomicLock) ); AtomicInstance atomic_ptr1_NULL(NULL); CPPUNIT_ASSERT( atomic_ptr1_NULL.content == (AtomicInstanceStub1 *)NULL ); CPPUNIT_ASSERT( checkLock(AtomicInstance::atomicLock) ); // this will lock AtomicInstance atomic_ptr1_1(ptr1_1); CPPUNIT_ASSERT( atomic_ptr1_1.content != (AtomicInstanceStub1 *)NULL ); CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); // now assign. Content has moved and should still be locked atomic_ptr1_NULL = atomic_ptr1_1; CPPUNIT_ASSERT( !checkLock(AtomicInstance::atomicLock) ); CPPUNIT_ASSERT( atomic_ptr1_NULL.content != (AtomicInstanceStub1 *)NULL ); CPPUNIT_ASSERT( atomic_ptr1_1.content == (AtomicInstanceStub1 *)NULL ); } CPPUNIT_ASSERT( checkLock(AtomicInstance::atomicLock) ); delete ptr1_1; }