瀏覽代碼

Merge branch 'ctk-dicom-tester'

* ctk-dicom-tester:
  ctkDICOMTesterTest1 was mysteriously failing
Julien Finet 14 年之前
父節點
當前提交
f6f1670ec8
共有 3 個文件被更改,包括 116 次插入34 次删除
  1. 75 14
      Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest1.cpp
  2. 8 15
      Libs/DICOM/Core/ctkDICOMTester.cpp
  3. 33 5
      Libs/DICOM/Core/ctkDICOMTester.h

+ 75 - 14
Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest1.cpp

@@ -1,5 +1,6 @@
 // Qt includes
 // Qt includes
 #include <QCoreApplication>
 #include <QCoreApplication>
+#include <QFileInfo>
 
 
 // ctkDICOMCore includes
 // ctkDICOMCore includes
 #include "ctkDICOMTester.h"
 #include "ctkDICOMTester.h"
@@ -22,38 +23,98 @@ int ctkDICOMTesterTest1(int argc, char * argv [])
   if (argc > 1)
   if (argc > 1)
     {
     {
     tester.setDCMQRSCPExecutable(argv[1]);
     tester.setDCMQRSCPExecutable(argv[1]);
+    if (tester.dcmqrscpExecutable() != argv[1])
+      {
+       std::cerr << __LINE__
+                 << ": Failed to set dcmqrscp: " << argv[1]
+                 << " value:" << qPrintable(tester.dcmqrscpExecutable())
+                 << std::endl;
+       return EXIT_FAILURE;
+      }
     }
     }
   if (argc > 2)
   if (argc > 2)
     {
     {
     tester.setDCMQRSCPConfigFile(argv[2]);
     tester.setDCMQRSCPConfigFile(argv[2]);
+    if (tester.dcmqrscpConfigFile() != argv[2])
+      {
+       std::cerr << __LINE__
+                 << ": Failed to set dcmqrscp config file: " << argv[2]
+                 << " value:" << qPrintable(tester.dcmqrscpConfigFile())
+                 << std::endl;
+       return EXIT_FAILURE;
+      }
+    }
+
+  QString dcmqrscp(tester.dcmqrscpExecutable());
+  QString dcmqrscpConf(tester.dcmqrscpConfigFile());
+
+  if (!QFileInfo(dcmqrscp).exists() ||
+      !QFileInfo(dcmqrscp).isExecutable())
+    {
+    std::cerr << __LINE__
+              << ": Wrong dcmqrscp executable: " << qPrintable(dcmqrscp)
+              << std::endl;
+    }
+
+  if (!QFileInfo(dcmqrscpConf).exists() ||
+      !QFileInfo(dcmqrscpConf).isReadable())
+    {
+    std::cerr << __LINE__
+              << ": Wrong dcmqrscp executable: " << qPrintable(dcmqrscp)
+              << std::endl;
     }
     }
 
 
   QProcess* process = tester.startDCMQRSCP();
   QProcess* process = tester.startDCMQRSCP();
   if (!process)
   if (!process)
     {
     {
-    std::cerr << "Failed to start dcmqrscp" << argv[1] << " with config file:"
-              << argv[2] << std::endl;
+    std::cerr << __LINE__
+              << ": Failed to start dcmqrscp: " << qPrintable(dcmqrscp)
+              << " with config file:" << qPrintable(dcmqrscpConf) << std::endl;
+    return EXIT_FAILURE;
+    }
+  bool res = tester.stopDCMQRSCP();
+  if (!res)
+    {
+    std::cerr << __LINE__
+              << ": Failed to stop dcmqrscp: " << qPrintable(dcmqrscp)
+              << " with config file:" << qPrintable(dcmqrscpConf) << std::endl;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
-  tester.stopDCMQRSCP();
 
 
-  QProcess* process2 = tester.startDCMQRSCP();
-  if (!process2 || process2 == process)
+  process = tester.startDCMQRSCP();
+  if (!process)
     {
     {
-    std::cerr << "Failed to start dcmqrscp" << argv[1] << " with config file:"
-              << argv[2] << std::endl;
+    std::cerr << __LINE__
+              << ": Failed to start dcmqrscp: " << qPrintable(dcmqrscp)
+              << " with config file:" << qPrintable(dcmqrscpConf)
+              << std::endl;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
-  QProcess* process3 = tester.startDCMQRSCP();
-  if (!process3 || process3 != process2)
+  process = tester.startDCMQRSCP();
+  if (process)
     {
     {
-    std::cerr << "Failed to start dcmqrscp" << argv[1] << " with config file:"
-              << argv[2] << std::endl;
+    std::cerr << __LINE__
+              << ": Failed to start dcmqrscp: " << qPrintable(dcmqrscp)
+              << " with config file:"<< qPrintable(dcmqrscpConf) << std::endl;
+    return EXIT_FAILURE;
+    }
+  res = tester.stopDCMQRSCP();
+  if (!res)
+    {
+    std::cerr << __LINE__
+              << ": Failed to stop dcmqrscp: " << qPrintable(dcmqrscp)
+              << " with config file:" << qPrintable(dcmqrscpConf) << std::endl;
+    return EXIT_FAILURE;
+    }
+  // there should be no process to stop
+  res = tester.stopDCMQRSCP();
+  if (res)
+    {
+    std::cerr << __LINE__
+              << ": Failed to stop dcmqrscp: " << qPrintable(dcmqrscp)
+              << " with config file:" << qPrintable(dcmqrscpConf) << std::endl;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
-  tester.stopDCMQRSCP();
-  tester.stopDCMQRSCP();
-
   return EXIT_SUCCESS;
   return EXIT_SUCCESS;
 }
 }
 
 

+ 8 - 15
Libs/DICOM/Core/ctkDICOMTester.cpp

@@ -124,7 +124,7 @@ QString ctkDICOMTesterPrivate::findStoreSCUExecutable()const
 void ctkDICOMTesterPrivate::printProcessOutputs(const QString& program, QProcess* process)const
 void ctkDICOMTesterPrivate::printProcessOutputs(const QString& program, QProcess* process)const
 {
 {
   QTextStream out(stdout);
   QTextStream out(stdout);
-  out << program << "finished.\n";
+  out << "Process " << program << " is finished.\n";
 
 
   QByteArray standardOutput = process->readAllStandardOutput();
   QByteArray standardOutput = process->readAllStandardOutput();
   if (standardOutput.count())
   if (standardOutput.count())
@@ -229,7 +229,7 @@ QProcess* ctkDICOMTester::startDCMQRSCP()
   Q_D(ctkDICOMTester);
   Q_D(ctkDICOMTester);
   if (d->DCMQRSCPProcess)
   if (d->DCMQRSCPProcess)
     {
     {
-    return d->DCMQRSCPProcess;
+    return 0;
     }
     }
   d->DCMQRSCPProcess = new QProcess(this);
   d->DCMQRSCPProcess = new QProcess(this);
 
 
@@ -241,16 +241,9 @@ QProcess* ctkDICOMTester::startDCMQRSCP()
   //dcmqrscp_args << "--debug" << "--verbose";
   //dcmqrscp_args << "--debug" << "--verbose";
   dcmqrscpArgs << QString::number(d->DCMQRSCPPort);
   dcmqrscpArgs << QString::number(d->DCMQRSCPPort);
 
 
-  try
-    {
-    d->DCMQRSCPProcess->start(d->DCMQRSCPExecutable, dcmqrscpArgs);
-    d->DCMQRSCPProcess->waitForStarted();
-    }
-  catch (std::exception e)
-    {
-    delete d->DCMQRSCPProcess;
-    d->DCMQRSCPProcess = 0;
-    }
+  d->DCMQRSCPProcess->start(d->DCMQRSCPExecutable, dcmqrscpArgs);
+  d->DCMQRSCPProcess->waitForStarted(-1);
+
   return d->DCMQRSCPProcess;
   return d->DCMQRSCPProcess;
 }
 }
 
 
@@ -264,8 +257,8 @@ bool ctkDICOMTester::stopDCMQRSCP()
     }
     }
 
 
   d->DCMQRSCPProcess->kill();
   d->DCMQRSCPProcess->kill();
-  bool res = d->DCMQRSCPProcess->waitForFinished();
-  
+  bool res = d->DCMQRSCPProcess->waitForFinished(-1);
+
   d->printProcessOutputs("DCMQRSCP", d->DCMQRSCPProcess);
   d->printProcessOutputs("DCMQRSCP", d->DCMQRSCPProcess);
 
 
   delete d->DCMQRSCPProcess;
   delete d->DCMQRSCPProcess;
@@ -299,7 +292,7 @@ bool ctkDICOMTester::storeData(const QStringList& data)
   storescuArgs << data;
   storescuArgs << data;
   
   
   storeSCU.start(d->StoreSCUExecutable, storescuArgs);
   storeSCU.start(d->StoreSCUExecutable, storescuArgs);
-  bool res = storeSCU.waitForFinished();
+  bool res = storeSCU.waitForFinished(-1);
 
 
   d->printProcessOutputs("StoreSCU", &storeSCU);
   d->printProcessOutputs("StoreSCU", &storeSCU);
   return res;
   return res;

+ 33 - 5
Libs/DICOM/Core/ctkDICOMTester.h

@@ -29,9 +29,18 @@ class QProcess;
 #include "ctkDICOMCoreExport.h"
 #include "ctkDICOMCoreExport.h"
 class ctkDICOMTesterPrivate;
 class ctkDICOMTesterPrivate;
 
 
+/** \brief Utility class to test DICOM network applications
+    A simple DICOM archive server can be run (startDCMQRSCP()), and images
+    can be stored into the server using storeData(). It internally uses
+    storeSCU.
+ */
 class CTK_DICOM_CORE_EXPORT ctkDICOMTester : public QObject
 class CTK_DICOM_CORE_EXPORT ctkDICOMTester : public QObject
 {
 {
   Q_OBJECT
   Q_OBJECT
+  Q_PROPERTY(QString dcmqrscpExecutable READ dcmqrscpExecutable WRITE setDCMQRSCPExecutable)
+  Q_PROPERTY(QString dcmqrscpConfigFile READ dcmqrscpConfigFile WRITE setDCMQRSCPConfigFile)
+  Q_PROPERTY(QString storeSCUExecutable READ storeSCUExecutable WRITE setStoreSCUExecutable)
+  Q_PROPERTY(int dcmqrscpPort READ dcmqrscpPort WRITE setDCMQRSCPPort)
 public:
 public:
   ctkDICOMTester(QObject* parent = 0);
   ctkDICOMTester(QObject* parent = 0);
   explicit ctkDICOMTester(const QString& dcmqrscp, const QString& configFile, QObject* parent = 0);
   explicit ctkDICOMTester(const QString& dcmqrscp, const QString& configFile, QObject* parent = 0);
@@ -39,20 +48,39 @@ public:
 
 
   void setDCMQRSCPExecutable(const QString& dcmqrscp);
   void setDCMQRSCPExecutable(const QString& dcmqrscp);
   QString dcmqrscpExecutable()const;
   QString dcmqrscpExecutable()const;
-  
+
   void setDCMQRSCPConfigFile(const QString& configFile);
   void setDCMQRSCPConfigFile(const QString& configFile);
   QString dcmqrscpConfigFile()const;
   QString dcmqrscpConfigFile()const;
-  
+
   void setStoreSCUExecutable(const QString& storescu);
   void setStoreSCUExecutable(const QString& storescu);
   QString storeSCUExecutable()const;
   QString storeSCUExecutable()const;
-  
+
+  /** Port number [0,65365] where the dcmqrscp and storescu communicate.
+      Changing the port won't change the port of any running process.
+      You must stop and restart any process you want to have its port changed
+  */
   void setDCMQRSCPPort(int port);
   void setDCMQRSCPPort(int port);
   int dcmqrscpPort()const;
   int dcmqrscpPort()const;
-  
+
+  /** Starts a new DCMQRSCP as a separate process. The process is running until
+      stopDCMQRSCP is called or ctkDICOMTester is destroyed.
+      Only one process of DCMQRSCP can be running at a time.
+      Calling startDCMQRSCP() while a DCMQRSCP process is already running
+      results into a no-op. The return value is 0.
+      \sa QProcess::start(),
+   */
   QProcess* startDCMQRSCP();
   QProcess* startDCMQRSCP();
+
+  /** Stop the running DCMQRSCP process. Returns it's exit status or false if
+      there is no running process.
+  */
   bool stopDCMQRSCP();
   bool stopDCMQRSCP();
 
 
-  /// Pushes data using storeSCU
+  /** Pushes data (DCM images) using DCMTK storeSCU app. It creates a separate
+      process and waits for its termination.
+      To be working, dcmqrscp must be running
+      \sa startDCMQRSCP()
+   */
   bool storeData(const QStringList& data);
   bool storeData(const QStringList& data);
 
 
 protected:
 protected: