Classes | Namespaces | Functions

mitkDataStorageTest.cpp File Reference

#include <fstream>
#include <algorithm>
#include "mitkImage.h"
#include "mitkSurface.h"
#include "mitkStringProperty.h"
#include "mitkColorProperty.h"
#include "mitkGroupTagProperty.h"
#include "mitkDataNode.h"
#include "mitkReferenceCountWatcher.h"
#include "mitkDataStorage.h"
#include "mitkStandaloneDataStorage.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateDimension.h"
#include "mitkNodePredicateData.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateSource.h"
#include "mitkMessage.h"
#include "mitkStandardFileLocations.h"
#include "mitkPicFileReader.h"
#include "mitkTestingMacros.h"

Go to the source code of this file.

Classes

class  mitk::TestStandaloneDataStorage
class  DSEventReceiver
struct  ItkDeleteEventListener
 a class for checking if the datastorage is really thread safe More...

Namespaces

namespace  mitk
 

Qmitk.


Functions

void TestDataStorage (mitk::DataStorage *ds)
 Test for the DataStorage class and its associated classes (e.g. the predicate classes) This method will be called once for each subclass of DataStorage.
int mitkDataStorageTest (int, char *[])

Function Documentation

int mitkDataStorageTest ( int  ,
char *  [] 
)

Definition at line 132 of file mitkDataStorageTest.cpp.

References MITK_TEST_BEGIN, MITK_TEST_CONDITION_REQUIRED, MITK_TEST_END, MITK_TEST_FAILED_MSG, MITK_TEST_OUTPUT, mitk::StandaloneDataStorage::New(), mitk::DataNode::New(), mitk::TestStandaloneDataStorage::New(), and TestDataStorage().

{
  MITK_TEST_BEGIN("DataStorageTest");

  // muellerm: test observer tag remove
  mitk::TestStandaloneDataStorage::Pointer testDS
      = mitk::TestStandaloneDataStorage::New();
  mitk::DataNode::Pointer n1 = mitk::DataNode::New();
  testDS->Add(n1);
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetModifiedObserverTags().size()==1, "Testing if modified"
      " observer was added.");
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetDeletedObserverTags().size()==1, "Testing if delete"
      " observer was added.");
  testDS->Remove(n1);
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetModifiedObserverTags().size()==0, "Testing if modified"
      " observer was removed.");
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetDeletedObserverTags().size()==0, "Testing if delete"
      " observer was removed.");

  /* Create StandaloneDataStorage */
  MITK_TEST_OUTPUT( << "Create StandaloneDataStorage : ");
  mitk::StandaloneDataStorage::Pointer sds;
  try
  {
    sds = mitk::StandaloneDataStorage::New();
    MITK_TEST_CONDITION_REQUIRED(sds.IsNotNull(), "Testing Instatiation");
  }
  catch (...)
  {
    MITK_TEST_FAILED_MSG( << "Exception during creation of StandaloneDataStorage");
  }

  MITK_TEST_OUTPUT( << "Testing StandaloneDataStorage: ");
  TestDataStorage(sds);
  // TODO: Add specific StandaloneDataStorage Tests here
  sds = NULL;

  MITK_TEST_END();
}
void TestDataStorage ( mitk::DataStorage ds )

Test for the DataStorage class and its associated classes (e.g. the predicate classes) This method will be called once for each subclass of DataStorage.

* Requesting *direct* derived objects with multiple parents/derivations */

* Checking for circular derivation relationships can not be performed, because the internal derivations datastructure

Definition at line 179 of file mitkDataStorageTest.cpp.

References mitk::DataStorage::Add(), mitk::DataStorage::AddNodeEvent, mitk::DataStorage::ComputeBoundingGeometry3D(), mitk::DataStorage::GetAll(), mitk::DataStorage::GetDerivations(), mitk::DataStorage::GetGroupTags(), mitk::StandardFileLocations::GetInstance(), mitk::DataStorage::GetNamedDerivedNode(), mitk::DataStorage::GetNamedNode(), mitk::DataStorage::GetNamedObject(), mitk::DataStorage::GetNode(), mitk::DataStorage::GetSources(), mitk::DataStorage::GetSubset(), MITK_TEST_CONDITION, MITK_TEST_CONDITION_REQUIRED, MITK_TEST_FAILED_MSG, MITK_TEST_FOR_EXCEPTION, MITK_TEST_FOR_EXCEPTION_BEGIN, MITK_TEST_FOR_EXCEPTION_END, MITK_TEST_OUTPUT, mitk::StandaloneDataStorage::New(), mitk::NodePredicateNot::New(), mitk::NodePredicateOr::New(), mitk::NodePredicateAnd::New(), mitk::ColorProperty::New(), mitk::NodePredicateData::New(), mitk::NodePredicateDimension::New(), mitk::NodePredicateDataType::New(), mitk::NodePredicateProperty::New(), mitk::GroupTagProperty::New(), mitk::Surface::New(), mitk::StringProperty::New(), mitk::DataNode::New(), mitk::PicFileReader::New(), DSEventReceiver::OnAdd(), DSEventReceiver::OnRemove(), mitk::DataStorage::Remove(), mitk::DataStorage::RemoveNodeEvent, and ItkDeleteEventListener::SetNode().

Referenced by mitkDataStorageTest().

{
  /* DataStorage valid? */
  MITK_TEST_CONDITION_REQUIRED(ds != NULL, "DataStorage valid?");

  // load test image
  mitk::StandardFileLocations::Pointer locator = mitk::StandardFileLocations::GetInstance();
  MITK_TEST_CONDITION_REQUIRED(locator.IsNotNull(),"Instantiating StandardFileLocations");
  std::string filename = locator->FindFile("US4DCyl.pic.gz", "Core/Code/Testing/Data/");

  mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New();
  reader -> SetFileName(filename.c_str());
  reader -> Update();
  mitk::Image::Pointer image = reader -> GetOutput();

  // create some DataNodes to fill the ds
  mitk::DataNode::Pointer n1 = mitk::DataNode::New();   // node with image and name property
//  mitk::Image::Pointer image = mitk::Image::New();
//  unsigned int imageDimensions[] = { 10, 10, 10, 10 };
//  mitk::PixelType pt(typeid(int));
//  image->Initialize( pt, 4, imageDimensions );
  n1->SetData(image);
  n1->SetProperty("name", mitk::StringProperty::New("Node 1 - Image Node"));
  mitk::DataStorage::SetOfObjects::Pointer parents1 = mitk::DataStorage::SetOfObjects::New();

  mitk::DataNode::Pointer n2 = mitk::DataNode::New();   // node with surface and name and color properties
  mitk::Surface::Pointer surface = mitk::Surface::New();
  n2->SetData(surface);
  n2->SetProperty("name", mitk::StringProperty::New("Node 2 - Surface Node"));
  mitk::Color color;  color.Set(1.0f, 1.0f, 0.0f);
  n2->SetColor(color);
  n2->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
  mitk::DataStorage::SetOfObjects::Pointer parents2 = mitk::DataStorage::SetOfObjects::New();
  parents2->InsertElement(0, n1);  // n1 (image node) is source of n2 (surface node)

  mitk::DataNode::Pointer n3 = mitk::DataNode::New();   // node without data but with name property
  n3->SetProperty("name", mitk::StringProperty::New("Node 3 - Empty Node"));
  n3->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
  n3->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
  mitk::DataStorage::SetOfObjects::Pointer parents3 = mitk::DataStorage::SetOfObjects::New();
  parents3->InsertElement(0, n2);  // n2 is source of n3

  mitk::DataNode::Pointer n4 = mitk::DataNode::New();   // node without data but with color property
  n4->SetColor(color);
  n4->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
  mitk::DataStorage::SetOfObjects::Pointer parents4 = mitk::DataStorage::SetOfObjects::New();
  parents4->InsertElement(0, n2);
  parents4->InsertElement(1, n3);  // n2 and n3 are sources of n4

  mitk::DataNode::Pointer n5 = mitk::DataNode::New();   // extra node
  n5->SetProperty("name", mitk::StringProperty::New("Node 5"));

  try /* adding objects */
  {
    /* Add an object */
    ds->Add(n1, parents1);
    MITK_TEST_CONDITION_REQUIRED((ds->GetAll()->Size() == 1) && (ds->GetAll()->GetElement(0) == n1), "Testing Adding a new object");

    /* Check exception on adding the same object again */
    MITK_TEST_OUTPUT( << "Check exception on adding the same object again: ");
    MITK_TEST_FOR_EXCEPTION(..., ds->Add(n1, parents1));
    MITK_TEST_CONDITION(ds->GetAll()->Size() == 1, "Test if object count is correct after exception");

    /* Add an object that has a source object */
    ds->Add(n2, parents2);
    MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 2, "Testing Adding an object that has a source object");

    /* Add some more objects needed for further tests */
    ds->Add(n3, parents3);   // n3 object that has name property and one parent
    ds->Add(n4, parents4);   // n4 object that has color property
    ds->Add(n5);             // n5 has no parents
    MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 5, "Adding some more objects needed for further tests");
  }
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exeption during object creation");
  }

  try  /* object retrieval methods */
  {
    /* Requesting all Objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();

      MITK_TEST_CONDITION(
        (stlAll.size() == 5)  // check if all tree nodes are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()),
        "Testing GetAll()"
        );
    }
    /* Requesting a named object */
    {
      mitk::NodePredicateProperty::Pointer predicate(mitk::NodePredicateProperty::New("name", mitk::StringProperty::New("Node 2 - Surface Node")));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting a named object");
    }

    /* Requesting objects of specific data type */
    {
      mitk::NodePredicateDataType::Pointer predicate(mitk::NodePredicateDataType::New("Image"));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific data type")
    }
    /* Requesting objects of specific dimension */
    {
      mitk::NodePredicateDimension::Pointer predicate(mitk::NodePredicateDimension::New( 4 ));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific dimension")
    }
    /* Requesting objects with specific data object */
    {
      mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(image));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects with specific data object")
    }
    /* Requesting objects with NULL data */
    {
      mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(NULL));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(all->begin(), all->end(), n3) != all->end())
        && (std::find(all->begin(), all->end(), n4) != all->end())
        && (std::find(all->begin(), all->end(), n5) != all->end())
        , "Requesting objects with NULL data");
    }
    /* Requesting objects that meet a conjunction criteria */
    {
      mitk::NodePredicateDataType::Pointer p1 = mitk::NodePredicateDataType::New("Surface");
      mitk::NodePredicateProperty::Pointer p2 = mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color));
      mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New();
      predicate->AddPredicate(p1);
      predicate->AddPredicate(p2);  // objects must be of datatype "Surface" and have red color (= n2)
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting objects that meet a conjunction criteria");
    }
    /* Requesting objects that meet a disjunction criteria */
    {
      mitk::NodePredicateDataType::Pointer p1(mitk::NodePredicateDataType::New("Image"));
      mitk::NodePredicateProperty::Pointer p2(mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color)));
      mitk::NodePredicateOr::Pointer predicate = mitk::NodePredicateOr::New();
      predicate->AddPredicate(p1);
      predicate->AddPredicate(p2);  // objects must be of datatype "Surface" or have red color (= n1, n2, n4)
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(all->begin(), all->end(), n1) != all->end())
        && (std::find(all->begin(), all->end(), n2) != all->end())
        && (std::find(all->begin(), all->end(), n4) != all->end()),
        "Requesting objects that meet a disjunction criteria");
    }
    /* Requesting objects that do not meet a criteria */
    {
      mitk::ColorProperty::Pointer cp = mitk::ColorProperty::New(color);
      mitk::NodePredicateProperty::Pointer proppred(mitk::NodePredicateProperty::New("color", cp));
      mitk::NodePredicateNot::Pointer predicate(mitk::NodePredicateNot::New(proppred));

      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3) // check if correct objects are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()), "Requesting objects that do not meet a criteria");
    }

    /* Requesting *direct* source objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, NULL, true); // Get direct parents of n3 (=n2)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
        "Requesting *direct* source objects");
    }

    /* Requesting *all* source objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, NULL, false); // Get all parents of n3 (= n1 + n2)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2)
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
        "Requesting *all* source objects"); // check if n1 and n2 are the resultset
    }

    /* Requesting *all* sources of object with multiple parents */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, NULL, false); // Get all parents of n4 (= n1 + n2 + n3)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
        , "Requesting *all* sources of object with multiple parents");
    }

    /* Requesting *direct* derived objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, NULL, true); // Get direct childs of n1 (=n2)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1)
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())// check if n1 is the resultset
        , "Requesting *direct* derived objects");

    }


    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n2, NULL, true); // Get direct childs of n2 (=n3 + n4)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2)
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n3 is the resultset
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()) // check if n4 is the resultset
        , "Requesting *direct* derived objects with multiple parents/derivations");
    }

    //* Requesting *all* derived objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, NULL, false); // Get all childs of n1 (=n2, n3, n4)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        , "Requesting *all* derived objects");
    }

    /* Checking for circular source relationships */
    {
      parents1->InsertElement(0, n4);   // make n1 derived from n4 (which is derived from n2, which is derived from n1)
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, NULL, false); // Get all parents of n4 (= n1 + n2 + n3, not n4 itself and not multiple versions of the nodes!)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
        , "Checking for circular source relationships");
    }

    //   can not be accessed from the outside. (Therefore it should not be possible to create these circular relations */

    //* Checking GroupTagProperty */
    {
      mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
      mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 1", tp));
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2) // check if n2 and n3 are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        , "Checking GroupTagProperty");
    }

    /* Checking GroupTagProperty 2 */
    {
      mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
      mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 2", tp));
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2) // check if n3 and n4 are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        , "Checking GroupTagProperty 2");

    }

    /* Checking direct sources with condition */
    {
      mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Surface");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, true);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) // check if n2 is in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        , "checking direct sources with condition");
    }

    /* Checking all sources with condition */
    {
      mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Image");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) // check if n1 is in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        , "Checking all sources with condition");
    }

    /* Checking all sources with condition with empty resultset */
    {
      mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("VesselTree");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
      MITK_TEST_CONDITION(all->Size() == 0 , "Checking all sources with condition with empty resultset"); // check if resultset is empty
    }

    /* Checking direct derivations with condition */
    {
      mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, true);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) // check if n2 is in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        , "Checking direct derivations with condition");
    }

    /* Checking all derivations with condition */
    {
      mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");

      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, false);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2) // check if n2 and n4 are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        , "Checking direct derivations with condition");
    }

    /* Checking named node method */
    MITK_TEST_CONDITION(ds->GetNamedNode("Node 2 - Surface Node") == n2, "Checking named node method");
    MITK_TEST_CONDITION(ds->GetNamedNode(std::string("Node 2 - Surface Node")) == n2, "Checking named node(std::string) method");

    /* Checking named node method with wrong name */
    MITK_TEST_CONDITION(ds->GetNamedNode("This name does not exist") == NULL, "Checking named node method with wrong name");

    /* Checking named object method */
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>("Node 1 - Image Node") == image, "Checking named object method");
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>(std::string("Node 1 - Image Node")) == image, "Checking named object(std::string) method");

    /* Checking named object method with wrong DataType */
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Surface>("Node 1 - Image Node") == NULL, "Checking named object method with wrong DataType");

    /* Checking named object method with wrong name */
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>("This name does not exist") == NULL, "Checking named object method with wrong name");

    /* Checking GetNamedDerivedNode with valid name and direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 2 - Surface Node", n1, true) == n2, "Checking GetNamedDerivedNode with valid name & direct derivation only");

    /* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("wrong name", n1, true) == NULL, "Checking GetNamedDerivedNode with invalid name & direct derivation only");

    /* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, false) == n3, "Checking GetNamedDerivedNode with invalid name & direct derivation only");


    /* Checking GetNamedDerivedNode with valid Name but direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, true) == NULL, "Checking GetNamedDerivedNode with valid Name but direct derivation only");

    /* Checking GetNode with valid predicate */
    {
      mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("Image"));
      MITK_TEST_CONDITION(ds->GetNode(p) == n1, "Checking GetNode with valid predicate");
    }
    /* Checking GetNode with invalid predicate */
    {
      mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("PointSet"));
      MITK_TEST_CONDITION(ds->GetNode(p) == NULL, "Checking GetNode with invalid predicate");
    }

  } // object retrieval methods
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exeption during object retrieval (GetXXX() Methods)");
  }

  try  /* object removal methods */
  {

    /* Checking removal of a node without relations */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));
      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      ds->Add(extra);
      MITK_TEST_CONDITION(ds->GetNamedNode("extra") == extra, "Adding extra node");
      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        , "Checking removal of a node without relations");
      extra = NULL;
    }

    /* Checking removal of a node with a parent */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));

      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      ds->Add(extra, n1);   // n1 is parent of extra

      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetDerivations(n1)->Size() == 2)   // n2 and extra should be derived from n1
        , "Adding extra node");
      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetDerivations(n1)->Size() == 1)
        , "Checking removal of a node with a parent");
      extra = NULL;
    }

    /* Checking removal of a node with two parents */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));

      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
      p->push_back(n1);
      p->push_back(n2);
      ds->Add(extra, p);   // n1 and n2 are parents of extra


      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetDerivations(n1)->Size() == 2)    // n2 and extra should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 3)
        , "add extra node");

      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetDerivations(n1)->Size() == 1)   // after remove, only n2 should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 2)   // after remove, only n3 and n4 should be derived from n2
        , "Checking removal of a node with two parents");
      extra = NULL;
    }

    /* Checking removal of a node with two derived nodes */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));
      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      ds->Add(extra);
      mitk::DataNode::Pointer d1 = mitk::DataNode::New();
      d1->SetProperty("name", mitk::StringProperty::New("d1"));
      ds->Add(d1, extra);
      mitk::DataNode::Pointer d2 = mitk::DataNode::New();
      d2->SetProperty("name", mitk::StringProperty::New("d2"));
      ds->Add(d2, extra);

      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetNamedNode("d1") == d1)
        && (ds->GetNamedNode("d2") == d2)
        && (ds->GetSources(d1)->Size() == 1)    // extra should be source of d1
        && (ds->GetSources(d2)->Size() == 1)    // extra should be source of d2
        && (ds->GetDerivations(extra)->Size() == 2)    // d1 and d2 should be derived from extra
        , "add extra node");

      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (ds->GetNamedNode("d1") == d1)
        && (ds->GetNamedNode("d2") == d2)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetSources(d1)->Size() == 0)   // after remove, d1 should not have a source anymore
        && (ds->GetSources(d2)->Size() == 0)   // after remove, d2 should not have a source anymore
        , "Checking removal of a node with two derived nodes");
      extra = NULL;
    }

    /* Checking removal of a node with two parents and two derived nodes */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));
      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      mitk::ReferenceCountWatcher::Pointer n1watcher = new mitk::ReferenceCountWatcher(n1);
      int refCountbeforeDS = watcher->GetReferenceCount();

      mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
      p->push_back(n1);
      p->push_back(n2);
      ds->Add(extra, p);   // n1 and n2 are parents of extra

      mitk::DataNode::Pointer d1 = mitk::DataNode::New();
      d1->SetProperty("name", mitk::StringProperty::New("d1x"));
      ds->Add(d1, extra);
      mitk::DataNode::Pointer d2 = mitk::DataNode::New();
      d2->SetProperty("name", mitk::StringProperty::New("d2x"));
      ds->Add(d2, extra);

      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetNamedNode("d1x") == d1)
        && (ds->GetNamedNode("d2x") == d2)
        && (ds->GetSources(d1)->Size() == 1)    // extra should be source of d1
        && (ds->GetSources(d2)->Size() == 1)    // extra should be source of d2
        && (ds->GetDerivations(n1)->Size() == 2)    // n2 and extra should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 3)   // n3, n4 and extra should be derived from n2
        && (ds->GetDerivations(extra)->Size() == 2)    // d1 and d2 should be derived from extra
        , "add extra node");

      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (ds->GetNamedNode("d1x") == d1)
        && (ds->GetNamedNode("d2x") == d2)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetDerivations(n1)->Size() == 1)    // after remove, only n2 should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 2)    // after remove, only n3 and n4 should be derived from n2
        && (ds->GetSources(d1)->Size() == 0)        // after remove, d1 should not have a source anymore
        && (ds->GetSources(d2)->Size() == 0)       // after remove, d2 should not have a source anymore
        , "Checking removal of a node with two parents and two derived nodes");
      extra = NULL;
    }
  }
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exeption during object removal methods");
  }



  /* Checking for node is it's own parent exception */
  {
    MITK_TEST_FOR_EXCEPTION_BEGIN(...);
    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    extra->SetProperty("name", mitk::StringProperty::New("extra"));
    mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
    p->push_back(n1);
    p->push_back(extra); // extra is parent of extra!!!
    ds->Add(extra, p);
    MITK_TEST_FOR_EXCEPTION_END(...);
  }


  /* Checking reference count of node after add and remove */
  {
    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
    extra->SetProperty("name", mitk::StringProperty::New("extra"));
    mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
    p->push_back(n1);
    p->push_back(n3);
    ds->Add(extra, p);
    extra = NULL;
    ds->Remove(ds->GetNamedNode("extra"));
    MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Checking reference count of node after add and remove");
  }

  /* Checking removal of a node with two derived nodes [ dataStorage->GetDerivations( rootNode )] see bug #3426 */
  {
    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    extra->SetProperty("name", mitk::StringProperty::New("extra"));

    ds->Add(extra);
    mitk::DataNode::Pointer d1y = mitk::DataNode::New();
    d1y->SetProperty("name", mitk::StringProperty::New("d1y"));
    mitk::ReferenceCountWatcher::Pointer watcherD1y = new mitk::ReferenceCountWatcher(d1y);
    int refCountbeforeDS = watcherD1y->GetReferenceCount();
    ds->Add(d1y, extra);
    mitk::DataNode::Pointer d2y = mitk::DataNode::New();
    d2y->SetProperty("name", mitk::StringProperty::New("d2y"));
    ds->Add(d2y, extra);

    MITK_TEST_CONDITION(
      (ds->GetNamedNode("extra") == extra)
      && (ds->GetNamedNode("d1y") == d1y)
      && (ds->GetNamedNode("d2y") == d2y)
      && (ds->GetSources(d1y)->Size() == 1)    // extra should be source of d1y
      && (ds->GetSources(d2y)->Size() == 1)    // extra should be source of d2y
      && (ds->GetDerivations(extra)->Size() == 2)    // d1y and d2y should be derived from extra
      , "add extra node");

    ds->Remove(ds->GetDerivations( extra));
    MITK_TEST_CONDITION(
      (ds->GetNamedNode("extra") == extra)
      && (ds->GetNamedNode("d1y") == NULL) // d1y should be NULL now
      && (ds->GetNamedNode("d2y") == NULL) // d2y should be NULL now
      && (refCountbeforeDS == watcherD1y->GetReferenceCount())
      , "Checking removal of subset of two derived nodes from one parent node");

    ds->Remove(extra);
    MITK_TEST_CONDITION(
      (ds->GetNamedNode("extra") == NULL)
      , "Checking removal of a parent node");
    extra = NULL;
  }

  /* Checking GetGrouptags() */
  {
    const std::set<std::string> groupTags = ds->GetGroupTags();
    MITK_TEST_CONDITION(
      (groupTags.size() == 2)
      && (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 1") != groupTags.end())
      && (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 2") != groupTags.end())
      , "Checking GetGrouptags()");
  }


  /* Checking Event handling */
  DSEventReceiver listener;
  try
  {
    ds->AddNodeEvent += mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
    ds->RemoveNodeEvent += mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);

    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
    ds->Add(extra);

    MITK_TEST_CONDITION(listener.m_NodeAdded == extra.GetPointer(), "Checking AddEvent");

    ds->Remove(extra);
    MITK_TEST_CONDITION(listener.m_NodeRemoved == extra.GetPointer(), "Checking RemoveEvent");

    /* RemoveListener */
    ds->AddNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
    ds->RemoveNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);
    listener.m_NodeAdded = NULL;
    listener.m_NodeRemoved = NULL;
    ds->Add(extra);
    ds->Remove(extra);
    MITK_TEST_CONDITION((listener.m_NodeRemoved == NULL) && (listener.m_NodeAdded == NULL), "Checking RemoveListener");


    std::cout << "Pointer handling after event handling: " << std::flush;
    extra = NULL; // delete reference to the node. its memory should be freed now
    MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Pointer handling after event handling");
  }
  catch(...)
  {
    /* cleanup */
    ds->AddNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
    ds->RemoveNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);
    MITK_TEST_FAILED_MSG( << "Exception during object removal methods");
  }

  //Checking ComputeBoundingGeometry3D method*/
  const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
  mitk::TimeSlicedGeometry::Pointer geometry = ds->ComputeBoundingGeometry3D();
  MITK_TEST_CONDITION(geometry->GetTimeSteps()==4, "Test for number or time steps with ComputeBoundingGeometry()");
  mitk::TimeBounds timebounds = geometry->GetTimeBounds();
  MITK_TEST_CONDITION((timebounds[0]==0)&&(timebounds[1]==4),"Test for timebounds with ComputeBoundingGeometry()");
  for (unsigned int i=0; i<geometry->GetTimeSteps(); i++)
  {
    mitk::Geometry3D::Pointer subGeometry = geometry->GetGeometry3D(i);
    mitk::TimeBounds bounds = subGeometry->GetTimeBounds();
    MITK_TEST_CONDITION((bounds[0]==i)&&(bounds[1]==i+1),"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
  }
  geometry = ds->ComputeBoundingGeometry3D(all);
  MITK_TEST_CONDITION(geometry->GetTimeSteps()==4, "Test for number or time steps with ComputeBoundingGeometry(allNodes)");
  timebounds = geometry->GetTimeBounds();
  MITK_TEST_CONDITION((timebounds[0]==0)&&(timebounds[1]==4),"Test for timebounds with ComputeBoundingGeometry(allNodes)");
  for (unsigned int i=0; i<geometry->GetTimeSteps(); i++)
  {
    mitk::Geometry3D::Pointer subGeometry = geometry->GetGeometry3D(i);
    mitk::TimeBounds bounds = subGeometry->GetTimeBounds();
    MITK_TEST_CONDITION((bounds[0]==i)&&(bounds[1]==i+1),"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
  }

  // test for thread safety of DataStorage
  try
  {
    mitk::StandaloneDataStorage::Pointer standaloneDataStorage
        = mitk::StandaloneDataStorage::New();
    ItkDeleteEventListener listener( standaloneDataStorage );
    {
      mitk::DataNode::Pointer emptyNode = mitk::DataNode::New();
      mitk::DataNode* pEmptyNode = emptyNode;
      listener.SetNode( emptyNode );
      standaloneDataStorage->Add( emptyNode );
      emptyNode = 0; // emptyNode is still alive because standaloneDataStorage
                     // owns it
      standaloneDataStorage->Remove( pEmptyNode ); // this should not freeze the whole thing
    }
  }
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exception during testing DataStorage thread safe");
  }

  /* Clear DataStorage */
  ds->Remove(ds->GetAll());
  MITK_TEST_CONDITION(ds->GetAll()->Size() == 0, "Checking Clear DataStorage");
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines