Browse Source

ENH: set up test using dcmqrscp as a dummy 'pacs' and then push data to it and query/retrieve it

Steve Pieper 14 years ago
parent
commit
a21d3d0914

+ 1 - 0
Applications/Testing/CMakeLists.txt

@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(Cpp)

+ 56 - 0
Applications/Testing/Cpp/CMakeLists.txt

@@ -0,0 +1,56 @@
+SET(KIT ${PROJECT_NAME})
+
+CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
+  ctkDICOMApplicationTest1.cpp
+  )
+
+SET (TestsToRun ${Tests})
+REMOVE (TestsToRun ${KIT}CppTests.cpp)
+
+# Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
+# The following macro will read the target libraries from the file 'target_libraries.cmake'
+ctkMacroGetTargetLibraries(KIT_target_libraries)
+
+ADD_EXECUTABLE(${KIT}CppTests ${Tests})
+TARGET_LINK_LIBRARIES(${KIT}CppTests ${KIT_target_libraries})
+
+SET( KIT_TESTS ${CPP_TEST_PATH}/${KIT}CppTests)
+
+MACRO( SIMPLE_TEST  TESTNAME )
+  ADD_TEST( ${TESTNAME} ${KIT_TESTS} ${TESTNAME} )
+  SET_PROPERTY(TEST ${TESTNAME} PROPERTY LABELS ${PROJECT_NAME})
+ENDMACRO( SIMPLE_TEST  )
+
+# create a dcm query/retrieve service config file that points to the build dir
+set (DCMQRSCP_STORE_DIR ${CTK_BINARY_DIR}/Testing/Temporary)
+set (ctkDICOMRetrieve_STORE_DIR ${CTK_BINARY_DIR}/Testing/Temporary/ctkDICOMRetrieveStorage)
+set (DCMQRSCP_CONFIG ${CTK_BINARY_DIR}/Testing/Temporary/dcmqrscp.cfg)
+CONFIGURE_FILE( dcmqrscp.cfg.in ${DCMQRSCP_CONFIG} )
+
+set(CTK_APPLICATION_RUNTIME_DIRECTORY ${CTK_CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+if(WIN32)
+  set(CTK_APPLICATION_RUNTIME_DIRECTORY 
+        ${CTK_APPLICATION_RUNTIME_DIRECTORY}/${CMAKE_BUILD_TYPE})
+endif(WIN32)
+
+set(ctkDICOMQuery_EXECUTABLE ${CTK_APPLICATION_RUNTIME_DIRECTORY}/ctkDICOMQuery)
+set(ctkDICOMQuery_DB_FILE ${CTK_BINARY_DIR}/Testing/Temporary/ctkDICOMApplicationTest1.db)
+set(ctkDICOMRetrieve_EXECUTABLE ${CTK_APPLICATION_RUNTIME_DIRECTORY}/ctkDICOMRetrieve)
+
+#
+# Add Tests
+#
+
+ADD_TEST( ctkDICOMApplicationTest1 ${KIT_TESTS}
+          ctkDICOMApplicationTest1 
+               ${DCMTK_DCMQRSCP_EXECUTABLE} 
+               ${DCMQRSCP_CONFIG}
+               ${CTKData_DIR}/Data/DICOM/MRHEAD/000055.IMA
+               ${CTKData_DIR}/Data/DICOM/MRHEAD/000056.IMA
+               ${DCMTK_STORESCU_EXECUTABLE}
+               ${ctkDICOMQuery_EXECUTABLE}
+               ${ctkDICOMQuery_DB_FILE}
+               ${ctkDICOMRetrieve_EXECUTABLE}
+               ${ctkDICOMRetrieve_STORE_DIR}
+               )
+SET_PROPERTY(TEST ctkDICOMApplicationTest1 PROPERTY LABELS ${PROJECT_NAME})

+ 185 - 0
Applications/Testing/Cpp/ctkDICOMApplicationTest1.cpp

@@ -0,0 +1,185 @@
+
+// Qt includes
+#include <QTextStream>
+#include <QApplication>
+#include <QProcess>
+
+// STD includes
+#include <iostream>
+#include <cstdlib>
+
+  /*
+/pieper/ctk/latest/CTK-superbuild/CMakeExternals/Install/bin/dcmqrscp -c /pieper/ctk/latest/CTK-superbuild/CTK-build/Testing/Temporary/dcmqrscp.cfg -d -v
+
+storescu -aec COMMONTK -aet CTK_AE localhost 11112 /data/pieper-face-2005-05-11/1.2.840.113619.2.135.3596.6358736.5118.1115807980.182.UID/000001.SER/000001.IMA
+
+findscu -aet CTK_AE -aec COMMONTK -P -k 0010,0010=\* localhost 11112 patqry.dcm
+
+./CTK-build/bin/ctkDICOMQuery test.db CTK_AE COMMONTK localhost 11112
+
+
+./CTK-build/bin/ctkDICOMRetrieve 1.2.840.113619.2.135.3596.6358736.5118.1115807980.182  /tmp/hoot CTK_AE 11113 CTK_AE localhost 11112 CTK_CLIENT_AE
+*/
+
+int ctkDICOMApplicationTest1(int argc, char * argv []) {
+  
+  QApplication app(argc, argv);
+  QTextStream out(stdout);
+
+  if ( argc < 10 )
+  {
+    out << "ERROR: invalid arguments.  Should be:\n";
+    out << " ctkDICOMApplicationTest1 <dcmqrscp> <configfile> <dicomData1> <dcmData2> <storescu> <ctkDICOMQuery> <ctkDICOMRetrieve> <retrieveDirectory>\n";
+    return EXIT_FAILURE;
+  }
+
+  QString dcmqrscp_exe  (argv[1]);
+  QString dcmqrscp_cfg  (argv[2]);
+  QString dicomData1  (argv[3]);
+  QString dicomData2  (argv[4]);
+  QString storescu_exe  (argv[5]);
+  QString ctkDICOMQuery_exe  (argv[6]);
+  QString ctkDICOMQuery_db_file  (argv[7]);
+  QString ctkDICOMRetrieve_exe  (argv[8]);
+  QString ctkDICOMRetrieve_directory  (argv[9]);
+
+  //
+  // first, start the server process
+  //
+
+  QProcess *dcmqrscp = new QProcess(0);
+  QStringList dcmqrscp_args;
+  dcmqrscp_args << "--config" << dcmqrscp_cfg;
+  dcmqrscp_args << "--debug" << "--verbose";
+  dcmqrscp_args << "11112";
+
+  try
+  {
+    out << "starting server" << dcmqrscp_exe << "\n";
+    out << "with args " << dcmqrscp_args.join(" ") << "\n";
+    dcmqrscp->start(dcmqrscp_exe, dcmqrscp_args);
+    dcmqrscp->waitForStarted();
+  }
+  catch (std::exception e)
+  {
+    out << "ERROR: could not start server" << e.what();
+    return EXIT_FAILURE;
+  }
+
+
+  //
+  // now push some dicom data in using storescp
+  //
+
+  QProcess *storescu = new QProcess(0);
+  QStringList storescu_args;
+  storescu_args << "-aec" << "CTK_AE";
+  storescu_args << "-aet" << "CTK_AE";
+  storescu_args << "localhost" << "11112";
+  storescu_args << dicomData1;
+  storescu_args << dicomData2;
+
+  try
+  {
+    out << "running client" << storescu_exe << "\n";
+    out << "with args" << storescu_args.join(" ") << "\n";
+    storescu->start(storescu_exe, storescu_args);
+    storescu->waitForFinished();
+    out << "storescu Finished.\n";
+    out << "Standard Output:\n";
+    out << storescu->readAllStandardOutput();
+    out << "Standard Error:\n";
+    out << storescu->readAllStandardError();
+  }
+  catch (std::exception e)
+  {
+    out << "ERROR: could not start client" << e.what();
+    return EXIT_FAILURE;
+  }
+
+  //
+  // now query the server to see if the data arrived okay
+  // - our database file will be updated with metadata from the query
+  //
+
+  QProcess *ctkDICOMQuery = new QProcess(0);
+  QStringList ctkDICOMQuery_args;
+  ctkDICOMQuery_args << ctkDICOMQuery_db_file;
+  ctkDICOMQuery_args << "CTK_AE" << "CTK_AE";
+  ctkDICOMQuery_args << "localhost" << "11112";
+
+  try
+  {
+    out << "running client" << ctkDICOMQuery_exe << "\n";
+    out << "with args" << ctkDICOMQuery_args.join(" ") << "\n";
+    ctkDICOMQuery->start(ctkDICOMQuery_exe, ctkDICOMQuery_args);
+    ctkDICOMQuery->waitForFinished();
+    out << "ctkDICOMQuery Finished.\n";
+    out << "Standard Output:\n";
+    out << ctkDICOMQuery->readAllStandardOutput();
+    out << "Standard Error:\n";
+    out << ctkDICOMQuery->readAllStandardError();
+  }
+  catch (std::exception e)
+  {
+    out << "ERROR: could not start client" << e.what();
+    return EXIT_FAILURE;
+  }
+
+
+  //
+  // now do a retrieve into our download directory
+  //
+
+  // this is the study id of the dicom files we load from CTKData
+  QString studyUID("1.2.840.113619.2.135.3596.6358736.5118.1115807980.182");
+
+  QProcess *ctkDICOMRetrieve = new QProcess(0);
+  QStringList ctkDICOMRetrieve_args;
+  ctkDICOMRetrieve_args << studyUID;
+  ctkDICOMRetrieve_args << ctkDICOMRetrieve_directory;
+  ctkDICOMRetrieve_args << "CTK_AE" << "11113";
+  ctkDICOMRetrieve_args << "CTK_AE";
+  ctkDICOMRetrieve_args << "localhost" << "11112" << "CTK_CLIENT_AE";
+
+  try
+  {
+    out << "running client" << ctkDICOMRetrieve_exe << "\n";
+    out << "with args" << ctkDICOMRetrieve_args.join(" ") << "\n";
+    ctkDICOMRetrieve->start(ctkDICOMRetrieve_exe, ctkDICOMRetrieve_args);
+    ctkDICOMRetrieve->waitForFinished();
+    out << "ctkDICOMRetrieve Finished.\n";
+    out << "Standard Output:\n";
+    out << ctkDICOMRetrieve->readAllStandardOutput();
+    out << "Standard Error:\n";
+    out << ctkDICOMRetrieve->readAllStandardError();
+  }
+  catch (std::exception e)
+  {
+    out << "ERROR: could not start client" << e.what();
+    return EXIT_FAILURE;
+  }
+
+
+  //
+  // clients are finished, not kill server and print output
+  //
+  try
+  {
+    dcmqrscp->kill();
+    dcmqrscp->waitForFinished();
+    out << "dcmqrscp Finished.\n";
+    out << "Standard Output:\n";
+    out << dcmqrscp->readAllStandardOutput();
+    out << "Standard Error:\n";
+    out << dcmqrscp->readAllStandardError();
+  }
+  catch (std::exception e)
+  {
+    out << "ERROR: could not start client" << e.what();
+    return EXIT_FAILURE;
+  }
+
+  return EXIT_SUCCESS;
+}
+

+ 84 - 0
Applications/Testing/Cpp/dcmqrscp.cfg.in

@@ -0,0 +1,84 @@
+#-----------------------------------------------------------------------
+#
+# Example configuration file for the dcmqrdb and dcmqrti applications.
+#
+# - this file is specialized for use as a local 'pacs' simulator for testing
+#   ctkDICOM* applications
+# - the location of the dicom store is configured by cmake to be in the build tree
+#
+#-----------------------------------------------------------------------
+
+# Global Configuration Parameters
+NetworkType     = "tcp"
+NetworkTCPPort  = 11112
+MaxPDUSize      = 16384
+MaxAssociations = 16
+Display         = "no"
+
+HostTable BEGIN
+#
+# The HostTable defines symbolic names for collections of network
+# DICOM Application Entities.  A symbolic name can represent a single
+# application entity or it can represent a group of application entities.
+# Each DICOM application entity is defined by a triple consisting of 
+# Application Entitiy Title, host name and TCP/IP port number.
+#
+# Entry Format: SymbolicName = ( AETitle, HostName, Portnumber ), ...   |
+#               SymbolicName = SymbolicName, ...
+#
+# NOTE: in the current implementation you cannot substitute an IP address
+# for a hostname.
+#
+#ctk           = (ACME1, acmehost1, 5678)
+#acme2           = (ACME2, acmehost2, 5678)
+#acmeCTcompany   = acme1, acme2
+#united1         = (UNITED1, unitedhost1, 104)
+#united2         = (UNITED2, unitedhost2, 104)
+#unitedMRcompany = united1, united2
+#
+commontk        = (CTK_AE,localhost,11112)
+commontk_client = (CTK_CLIENT_AE, localhost, 11113)
+#
+HostTable END
+
+VendorTable BEGIN
+#
+# The VendorTable is used by the dcmqrdb and dcmqrti applications.
+# You can give a vendor name (r.h.s. entry below) to the dcmqrti 
+# program and it will talk to all hosts and AEs of the vendor.
+# The dcmqrdb program can use the vendor table to restrict move destination
+# to hosts belonging to a vendor.
+# Also, the dcmqrti and dcmqrdb programs use the name defined on the left hand side
+# as the vendor name to display above images.
+#
+# The format: 
+#       VendorName = SymbolicName
+# The symbolic name should be defined in the HostTable.
+#
+#"Acme CT Company"   = acmeCTcompany
+#"United MR Company" = unitedMRcompany
+"The Common Toolkit" = commontk
+"The Common Toolkit Client" = commontk_client
+#
+VendorTable END
+
+AETable BEGIN
+#
+# Each row of the AETable defines an Application Entities (AE) Title known
+# to the dcmqrdb application.  Each AE Title represents a separate
+# image database located in the specified file system directory (storage area).
+# Each AE Title has read/write, quota and peer access restrictions.
+#
+# Entry Format: AETitle  StorageArea  Access  Quota  Peers
+# AccessFormat: R | RW | W
+# Quota Format: ( maxStudies, maxBytesPerStudy )
+# Peers Format: ( Hostname, AETitle, Portnumber ), ...  |
+#               Entry in HostTable                      |
+#               ANY
+#
+#COMMON       /home/dicom/db/COMMON       R  (200, 1024mb) ANY
+#ACME_STORE   /home/dicom/db/ACME_STORE   RW (9, 1024mb)   acmeCTcompany
+#UNITED_STORE /home/dicom/db/UNITED_STORE RW (9, 1024mb)   unitedMRcompany
+CTK_AE     @DCMQRSCP_STORE_DIR@        RW (200, 1024mb) commontk
+#
+AETable END

+ 9 - 0
Applications/Testing/Cpp/target_libraries.cmake

@@ -0,0 +1,9 @@
+#
+# See CMake/ctkMacroGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK application.
+# 
+
+SET(target_libraries
+  CTKDICOMWidgets
+  )