From 3f611a5551fdc5299bf4406a3eac4391d0590c47 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Wed, 17 Jan 2024 16:57:17 -0500 Subject: [PATCH 1/5] ENH: Update ctkDICOMDatabaseTest2 to test use of lower and upper case tags Follow-up of 73ab63a2 ("BUG: Fix ctkDICOMDatabaseTest2 comparing upper-cased tag", 2024-01-12) --- .../Testing/Cpp/ctkDICOMDatabaseTest2.cpp | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp index 00c1b6606f..c66bb55e93 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp @@ -91,28 +91,25 @@ int ctkDICOMDatabaseTest2( int argc, char * argv [] ) // // Test that the tag interface works to parse ascii // - QString tag("0008,103e"); - unsigned short group, element; - if ( !database.tagToGroupElement(tag, group, element) ) - { - std::cerr << "ctkDICOMDatabase: could not parse tag" << std::endl; - return EXIT_FAILURE; - } - - if ( group != 0x8 || element != 0x103e ) - { - std::cerr << "ctkDICOMDatabase: expected: " << "0008,103e" << std::endl; - std::cerr << "ctkDICOMDatabase: got: " << group << " " << element << std::endl; - std::cerr << "ctkDICOMDatabase: parsed tag does not match group/element" << std::endl; - return EXIT_FAILURE; - } - - if ( database.groupElementToTag(group, element) != tag.toUpper() ) - { - std::cerr << "ctkDICOMDatabase: could not convert a uints to tag string" << std::endl; - return EXIT_FAILURE; - } + { + unsigned short group, element; + QString tag("0008,103E"); // upper case + CHECK_BOOL(database.tagToGroupElement(tag, group, element), true); + CHECK_INT(group, 0x8); + CHECK_INT(element, 0x103E); + } + { + unsigned short group, element; + QString tag("0008,103e"); // lower case + CHECK_BOOL(database.tagToGroupElement(tag, group, element), true); + CHECK_INT(group, 0x8); + CHECK_INT(element, 0x103E); + } + // + // Test that conversion from uints to tag string works + // + CHECK_QSTRING(database.groupElementToTag(0x8, 0x103E), "0008,103E"); // // Basic test: @@ -161,7 +158,7 @@ int ctkDICOMDatabaseTest2( int argc, char * argv [] ) return EXIT_FAILURE; } - + QString tag("0008,103E"); if (database.cachedTag(instanceUID, tag) != QString("")) { std::cerr << "ctkDICOMDatabase: tag cache should return empty string for unknown instance tag" << std::endl; From 791803c1a7046b38cfce3a2b99267deab64b9a29 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Wed, 17 Jan 2024 16:46:33 -0500 Subject: [PATCH 2/5] BUG: Fix argument processing and usage message in ctkDICOM tests The CTest driver automatically updates the first argument to match the test name. This commit ensures that only one argument is removed from the list before retrieving test-specific arguments, if any. Switch all DICOM tests to process arguments using the list returned by `QCoreApplication::arguments()`. Additionally, it updates the use of the command line parser in `ctkFileDialogTest1`. Co-authored-by: Davide Punzo --- .../Testing/Cpp/ctkDICOMApplicationTest1.cpp | 15 ++- .../ctkDICOM/Testing/Cpp/ctkDICOMTest1.cpp | 18 ++- .../ctkDICOM2/Testing/Cpp/ctkDICOM2Test1.cpp | 18 ++- .../Testing/Cpp/ctkDICOMDemoSCUTest1.cpp | 23 +++- .../Testing/Cpp/ctkDICOMHostTest1.cpp | 12 +- .../Testing/Cpp/ctkDICOMIndexerAppTest1.cpp | 18 ++- .../Core/Testing/Cpp/ctkDICOMCoreTest1.cpp | 40 ++++-- .../Testing/Cpp/ctkDICOMDatabaseTest2.cpp | 11 +- .../Testing/Cpp/ctkDICOMDatabaseTest3.cpp | 14 +- .../Testing/Cpp/ctkDICOMDatabaseTest4.cpp | 11 +- .../Testing/Cpp/ctkDICOMDatabaseTest5.cpp | 11 +- .../Testing/Cpp/ctkDICOMDatabaseTest6.cpp | 11 +- .../Core/Testing/Cpp/ctkDICOMModelTest1.cpp | 25 ++-- .../Core/Testing/Cpp/ctkDICOMQueryTest2.cpp | 17 +-- .../Testing/Cpp/ctkDICOMRetrieveTest2.cpp | 20 ++- .../Core/Testing/Cpp/ctkDICOMTesterTest1.cpp | 122 ++++++------------ .../Core/Testing/Cpp/ctkDICOMTesterTest2.cpp | 10 +- .../Testing/Cpp/ctkDICOMAppWidgetTest1.cpp | 8 +- .../Testing/Cpp/ctkDICOMBrowserTest1.cpp | 22 +++- .../Cpp/ctkDICOMDirectoryListWidgetTest1.cpp | 8 +- .../Testing/Cpp/ctkDICOMImageTest1.cpp | 17 ++- .../Testing/Cpp/ctkDICOMImportWidgetTest1.cpp | 8 +- .../Testing/Cpp/ctkDICOMItemViewTest1.cpp | 17 ++- .../Cpp/ctkDICOMListenerWidgetTest1.cpp | 8 +- .../Testing/Cpp/ctkDICOMModelTest2.cpp | 34 +++-- .../Testing/Cpp/ctkDICOMObjectModelTest1.cpp | 34 ++++- .../ctkDICOMQueryResultsTabWidgetTest1.cpp | 8 +- .../Cpp/ctkDICOMQueryRetrieveWidgetTest1.cpp | 9 +- .../Cpp/ctkDICOMServerNodeWidgetTest1.cpp | 8 +- .../Cpp/ctkDICOMThumbnailListWidgetTest1.cpp | 24 +++- .../Testing/Cpp/ctkFileDialogTest1.cpp | 5 +- 31 files changed, 381 insertions(+), 225 deletions(-) diff --git a/Applications/Testing/Cpp/ctkDICOMApplicationTest1.cpp b/Applications/Testing/Cpp/ctkDICOMApplicationTest1.cpp index b5b018db64..b65bbd42d2 100644 --- a/Applications/Testing/Cpp/ctkDICOMApplicationTest1.cpp +++ b/Applications/Testing/Cpp/ctkDICOMApplicationTest1.cpp @@ -206,10 +206,19 @@ int main(int argc, char * argv []) { QCoreApplication app(argc, argv); QTextStream out(stdout); - if ( argc < 10 ) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 9) { - out << "ERROR: invalid arguments. Should be:\n"; - out << " ctkDICOMApplicationTest1 \n"; + std::cerr << "ERROR: invalid or missing arguments.\n\n" + << "Usage: " << qPrintable(testName) + << " " + " " + " " + " " + " " + " \n"; return EXIT_FAILURE; } diff --git a/Applications/ctkDICOM/Testing/Cpp/ctkDICOMTest1.cpp b/Applications/ctkDICOM/Testing/Cpp/ctkDICOMTest1.cpp index 968dff12fa..a5a19dad6b 100644 --- a/Applications/ctkDICOM/Testing/Cpp/ctkDICOMTest1.cpp +++ b/Applications/ctkDICOM/Testing/Cpp/ctkDICOMTest1.cpp @@ -29,14 +29,22 @@ int ctkDICOMTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); - if (app.arguments().count() != 2) + + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { - std::cerr << "Line " << __LINE__ << " - Failed to run " << argv[0] << "\n" - << "Usage:\n" - << " " << argv[0] << " /path/to/ctkDICOM"; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } - QString command = app.arguments().at(1); + + QString command = arguments.at(0); + + std::cout << "Testing:\n" + << qPrintable(command) << std::endl; + QProcess process; process.start(command, /* arguments= */ QStringList()); bool res = process.waitForStarted(); diff --git a/Applications/ctkDICOM2/Testing/Cpp/ctkDICOM2Test1.cpp b/Applications/ctkDICOM2/Testing/Cpp/ctkDICOM2Test1.cpp index 407849c939..3ab9306d74 100644 --- a/Applications/ctkDICOM2/Testing/Cpp/ctkDICOM2Test1.cpp +++ b/Applications/ctkDICOM2/Testing/Cpp/ctkDICOM2Test1.cpp @@ -29,14 +29,22 @@ int ctkDICOM2Test1(int argc, char * argv []) { QCoreApplication app(argc, argv); - if (app.arguments().count() != 2) + + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { - std::cerr << "Line " << __LINE__ << " - Failed to run " << argv[0] << "\n" - << "Usage:\n" - << " " << argv[0] << " /path/to/ctkDICOM"; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } - QString command = app.arguments().at(1); + + QString command = arguments.at(0); + + std::cout << "Testing:\n" + << qPrintable(command) << std::endl; + QProcess process; process.start(command, /* arguments= */ QStringList()); bool res = process.waitForStarted(); diff --git a/Applications/ctkDICOMDemoSCU/Testing/Cpp/ctkDICOMDemoSCUTest1.cpp b/Applications/ctkDICOMDemoSCU/Testing/Cpp/ctkDICOMDemoSCUTest1.cpp index 2a2434df16..648ae2b3ff 100644 --- a/Applications/ctkDICOMDemoSCU/Testing/Cpp/ctkDICOMDemoSCUTest1.cpp +++ b/Applications/ctkDICOMDemoSCU/Testing/Cpp/ctkDICOMDemoSCUTest1.cpp @@ -29,19 +29,28 @@ int ctkDICOMDemoSCUTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); + + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) + { + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; + return EXIT_FAILURE; + } + + QString command = arguments.at(0); + QString peer("www.dicomserver.co.uk"); QString port("104"); QString aeTitle("MOVESCP"); QStringList parameters; parameters << peer << port << aeTitle; - if (argc < 2) - { - std::cerr << "Must specify path to ctkDICOMDemoSCU on command line\n"; - return EXIT_FAILURE; - } - std::cout << "Testing ctkDICOMDemoSCU: " << argv[1] << "\n"; - QString command = QString(argv[1]); + std::cout << "Testing:\n" + << qPrintable(command) << " " + << qPrintable(parameters.join(" ")) << std::endl; int res = QProcess::execute(command, parameters); if (res != EXIT_SUCCESS) diff --git a/Applications/ctkDICOMHost/Testing/Cpp/ctkDICOMHostTest1.cpp b/Applications/ctkDICOMHost/Testing/Cpp/ctkDICOMHostTest1.cpp index 38188e29ce..f134ae0aa5 100644 --- a/Applications/ctkDICOMHost/Testing/Cpp/ctkDICOMHostTest1.cpp +++ b/Applications/ctkDICOMHost/Testing/Cpp/ctkDICOMHostTest1.cpp @@ -33,14 +33,20 @@ int ctkDICOMHostTest1(int argc, char * argv []) QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); - arguments.pop_front(); // remove "program" name - if (!arguments.count()) + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { - std::cerr << "Usage: ctkDICOMHostTest1 /path/to/ctkDICOMHost" << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } QString command = arguments.at(0); + + std::cout << "Testing:\n" + << qPrintable(command) << std::endl; + QProcess process; process.start(command, /* arguments= */ QStringList()); bool res = process.waitForStarted(); diff --git a/Applications/ctkDICOMIndexer/Testing/Cpp/ctkDICOMIndexerAppTest1.cpp b/Applications/ctkDICOMIndexer/Testing/Cpp/ctkDICOMIndexerAppTest1.cpp index 084cd22388..5507ca8fb5 100644 --- a/Applications/ctkDICOMIndexer/Testing/Cpp/ctkDICOMIndexerAppTest1.cpp +++ b/Applications/ctkDICOMIndexer/Testing/Cpp/ctkDICOMIndexerAppTest1.cpp @@ -29,18 +29,28 @@ int ctkDICOMIndexerAppTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); + + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + QString database("test.db"); - if (argc < 2) + if (arguments.count() != 1) { - std::cerr << "Must specify path to ctkDICOMIndexer on command line\n"; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } - std::cout << "Testing ctkDICOMIndexer: " << argv[1] << "\n"; - QString command = QString(argv[1]); + + QString command = arguments.at(0); QStringList parameters; parameters << "--init" << database; + + std::cout << "Testing:\n" + << qPrintable(command) << " " + << qPrintable(parameters.join(" ")) << std::endl; + int res = QProcess::execute(command, parameters); if (res != EXIT_SUCCESS) { diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMCoreTest1.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMCoreTest1.cpp index 4200c53855..4458080284 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMCoreTest1.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMCoreTest1.cpp @@ -23,6 +23,9 @@ #include #include +// ctkCore includes +#include + // ctkDICOMCore includes #include "ctkDICOMDatabase.h" @@ -33,28 +36,37 @@ int ctkDICOMCoreTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); - QTextStream out(stdout); + + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 2) + { + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; + return EXIT_FAILURE; + } + + QString sqlFileName1(arguments.at(0)); + QString sqlFileName2(arguments.at(1)); + try { - ctkDICOMDatabase myCTK( argv[1] ); - out << "open db success\n"; - /// make sure it is empty and properly initialized - if (! myCTK.initializeDatabase() ) { - out << "ERROR: basic DB init failed"; - return EXIT_FAILURE; - }; + ctkDICOMDatabase myCTK(sqlFileName1); + CHECK_BOOL(myCTK.initializeDatabase(), true); + /// insert some sample data - if (! myCTK.initializeDatabase(argv[2]) ) { - out << "ERROR: sample DB init failed"; - return EXIT_FAILURE; - }; + CHECK_BOOL(myCTK.initializeDatabase(sqlFileName2.toUtf8()), true); + myCTK.closeDatabase(); - } + } catch (const std::exception& e) { - out << "ERROR: " << e.what(); + std::cerr << "Error when opening the data base file: " << argv[1] + << " error: " << e.what() << std::endl; return EXIT_FAILURE; } + return EXIT_SUCCESS; } diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp index c66bb55e93..62f811ea21 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest2.cpp @@ -39,14 +39,17 @@ int ctkDICOMDatabaseTest2( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - if (argc < 2) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { - std::cerr << "ctkDICOMDatabaseTest2: missing dicom filePath argument"; - std::cerr << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } - QString dicomFilePath(argv[1]); + QString dicomFilePath(arguments.at(0)); QTemporaryDir tempDirectory; CHECK_BOOL(tempDirectory.isValid(), true); diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest3.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest3.cpp index bda222c34d..183abdb418 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest3.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest3.cpp @@ -38,13 +38,19 @@ int ctkDICOMDatabaseTest3( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - if (argc <= 1) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { std::cerr << "Warning, no sql file given. Test stops" << std::endl; - std::cerr << "Usage: ctkDICOMDatabaseTest3 " << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } + QString sqlFileName(arguments.at(0)); + QTemporaryDir tempDirectory; CHECK_BOOL(tempDirectory.isValid(), true); @@ -59,9 +65,9 @@ int ctkDICOMDatabaseTest3( int argc, char * argv [] ) { ctkDICOMDatabase myCTK( databaseFileName ); - if (!myCTK.initializeDatabase(argv[1])) + if (!myCTK.initializeDatabase(sqlFileName.toUtf8())) { - std::cerr << "Error when initializing the data base with: " << argv[1] + std::cerr << "Error when initializing the data base with: " << qPrintable(sqlFileName) << " error: " << myCTK.lastError().toStdString(); return EXIT_FAILURE; } diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest4.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest4.cpp index 04b0bb22d9..b8809dac7a 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest4.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest4.cpp @@ -38,14 +38,17 @@ int ctkDICOMDatabaseTest4( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - if (argc < 2) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { - std::cerr << "ctkDICOMDatabaseTest2: missing dicom filePath argument"; - std::cerr << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } - QString dicomFilePath(argv[1]); + QString dicomFilePath(arguments.at(0)); QTemporaryDir tempDirectory; CHECK_BOOL(tempDirectory.isValid(), true); diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest5.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest5.cpp index 6736e63319..279a20a7bb 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest5.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest5.cpp @@ -38,14 +38,17 @@ int ctkDICOMDatabaseTest5( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - if (argc < 2) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { - std::cerr << "ctkDICOMDatabaseTest2: missing dicom filePath argument"; - std::cerr << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } - QString dicomFilePath(argv[1]); + QString dicomFilePath(arguments.at(0)); QTemporaryDir tempDirectory; CHECK_BOOL(tempDirectory.isValid(), true); diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest6.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest6.cpp index 182ce78ce8..4f28732f53 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest6.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMDatabaseTest6.cpp @@ -38,14 +38,17 @@ int ctkDICOMDatabaseTest6( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - if (argc < 2) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 1) { - std::cerr << "ctkDICOMDatabaseTest6: missing dicom filePath argument"; - std::cerr << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } - QString dicomFilePath(argv[1]); + QString dicomFilePath(arguments.at(0)); QTemporaryDir tempDirectory; CHECK_BOOL(tempDirectory.isValid(), true); diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMModelTest1.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMModelTest1.cpp index 81c90de165..d2ca63be40 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMModelTest1.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMModelTest1.cpp @@ -41,21 +41,28 @@ int ctkDICOMModelTest1( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - if (argc <= 2) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + if (arguments.count() != 2) { - std::cerr << "Warning, no sql file given. Test stops" << std::endl; - std::cerr << "Usage: qctkDICOMModelTest1 " << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } + QString databaseFile(arguments.at(0)); + QString sqlFileName(arguments.at(1)); + try { - ctkDICOMDatabase myCTK( argv[1] ); + ctkDICOMDatabase myCTK( databaseFile ); - if (!myCTK.initializeDatabase(argv[2])) + if (!myCTK.initializeDatabase(sqlFileName.toUtf8())) { - std::cerr << "Error when initializing the data base: " << argv[2] - << " error: " << myCTK.lastError().toStdString(); + std::cerr << "Error when initializing the data base: " << qPrintable(sqlFileName) + << " error: " << qPrintable(myCTK.lastError()) << std::endl; + return EXIT_FAILURE; } /* QSqlQuery toto("SELECT PatientsName as 'Name tt' FROM Patients ORDER BY \"Name tt\" ASC", myCTK.database()); @@ -92,8 +99,8 @@ int ctkDICOMModelTest1( int argc, char * argv [] ) } catch (const std::exception& e) { - std::cerr << "Error when opening the data base file: " << argv[1] - << " error: " << e.what(); + std::cerr << "Error when opening the data base file: " << qPrintable(databaseFile) + << " error: " << e.what() << std::endl; return EXIT_FAILURE; } } diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMQueryTest2.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMQueryTest2.cpp index 518fa3db12..e43dd32a96 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMQueryTest2.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMQueryTest2.cpp @@ -32,27 +32,24 @@ // STD includes #include -void ctkDICOMQueryTest2PrintUsage() -{ - std::cout << " ctkDICOMQueryTest2 images" << std::endl; -} // Test on a real local database int ctkDICOMQueryTest2( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - ctkDICOMTester tester; - tester.startDCMQRSCP(); - QStringList arguments = app.arguments(); - arguments.pop_front(); // remove application name - arguments.pop_front(); // remove test name + QString testName = arguments.takeFirst(); + if (!arguments.count()) { - ctkDICOMQueryTest2PrintUsage(); + std::cerr << "Usage: " << qPrintable(testName) + << " [...]" << std::endl; return EXIT_FAILURE; } + + ctkDICOMTester tester; + tester.startDCMQRSCP(); tester.storeData(arguments); ctkDICOMDatabase database; diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMRetrieveTest2.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMRetrieveTest2.cpp index 748cdf9c62..bc38a3df5d 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMRetrieveTest2.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMRetrieveTest2.cpp @@ -35,28 +35,26 @@ // STD includes #include -void ctkDICOMRetrieveTest2PrintUsage() -{ - std::cout << " ctkDICOMRetrieveTest2 images" << std::endl; -} // Test on a real local database int ctkDICOMRetrieveTest2( int argc, char * argv [] ) { QCoreApplication app(argc, argv); - ctkDICOMTester tester; - std::cerr << "ctkDICOMRetrieveTest2: Starting dcmqrscp\n"; - tester.startDCMQRSCP(); - QStringList arguments = app.arguments(); - arguments.pop_front(); // remove application name - arguments.pop_front(); // remove test name + QString testName = arguments.takeFirst(); + if (!arguments.count()) { - ctkDICOMRetrieveTest2PrintUsage(); + std::cerr << "Usage: " << qPrintable(testName) + << " [...]" << std::endl; return EXIT_FAILURE; } + + ctkDICOMTester tester; + std::cerr << "ctkDICOMRetrieveTest2: Starting dcmqrscp\n"; + tester.startDCMQRSCP(); + std::cerr << "ctkDICOMRetrieveTest2: Storing data to dcmqrscp\n"; tester.storeData(arguments); diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest1.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest1.cpp index ffaf3cece5..714638d081 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest1.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest1.cpp @@ -21,6 +21,10 @@ // Qt includes #include #include +#include + +// ctkCore includes +#include // ctkDICOMCore includes #include "ctkDICOMTester.h" @@ -29,112 +33,68 @@ #include #include -void printUsage() -{ - std::cout << " ctkDICOMTesterTest1 [] []" << std::endl; -} int ctkDICOMTesterTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + ctkDICOMTester tester; - if (argc > 1) + // Usage: ctkDICOMTesterTest1 [] [] + if (arguments.count() > 0) { - 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; - } + QString dcmqrscpExecutable(arguments.at(0)); + tester.setDCMQRSCPExecutable(dcmqrscpExecutable); + CHECK_QSTRING(tester.dcmqrscpExecutable(), dcmqrscpExecutable); } - if (argc > 2) + if (arguments.count() > 1) { + QString dcmqrscpConfigFile(arguments.at(1)); 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; - } + CHECK_QSTRING(tester.dcmqrscpConfigFile(), dcmqrscpConfigFile); } QString dcmqrscp(tester.dcmqrscpExecutable()); QString dcmqrscpConf(tester.dcmqrscpConfigFile()); - if (!QFileInfo(dcmqrscp).exists() || - !QFileInfo(dcmqrscp).isExecutable()) + if (dcmqrscp == "dcmqrscp") { - std::cerr << __LINE__ - << ": Wrong dcmqrscp executable: " << qPrintable(dcmqrscp) - << std::endl; + // If not found, assume the executable is in the PATH + dcmqrscp = QStandardPaths::findExecutable(dcmqrscp); } + CHECK_BOOL(QFileInfo::exists(dcmqrscp), true); + CHECK_BOOL(QFileInfo(dcmqrscp).isExecutable(), true); - if (!QFileInfo(dcmqrscpConf).exists() || - !QFileInfo(dcmqrscpConf).isReadable()) - { - std::cerr << __LINE__ - << ": Wrong dcmqrscp executable: " << qPrintable(dcmqrscp) - << std::endl; - } + CHECK_BOOL(QFileInfo::exists(dcmqrscpConf), true); + CHECK_BOOL(QFileInfo(dcmqrscpConf).isReadable(), true); QProcess* process = tester.startDCMQRSCP(); - if (!process) - { - 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; - } + // Check if dcmqrscp started + CHECK_NOT_NULL(process); + + // Check if dcmqrscp can be stopped + CHECK_BOOL(tester.stopDCMQRSCP(), true); + + // Check if dcmqrscp can be re-started process = tester.startDCMQRSCP(); - if (!process) - { - std::cerr << __LINE__ - << ": Failed to start dcmqrscp: " << qPrintable(dcmqrscp) - << " with config file:" << qPrintable(dcmqrscpConf) - << std::endl; - return EXIT_FAILURE; - } + CHECK_NOT_NULL(process); + + // Check if dcmqrscp is already running (in that + // case, it returns null) process = tester.startDCMQRSCP(); - if (process) - { - 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; - } + CHECK_NULL(process); + + // Check if dcmqrscp can be stopped + CHECK_BOOL(tester.stopDCMQRSCP(), true); + // 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; - } + CHECK_BOOL(tester.stopDCMQRSCP(), false); + return EXIT_SUCCESS; } diff --git a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest2.cpp b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest2.cpp index 34b822730a..4b0176f20a 100644 --- a/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest2.cpp +++ b/Libs/DICOM/Core/Testing/Cpp/ctkDICOMTesterTest2.cpp @@ -29,20 +29,18 @@ #include #include -void ctkDICOMTesterTest2PrintUsage() -{ - std::cout << " ctkDICOMTesterTest2 images" << std::endl; -} int ctkDICOMTesterTest2(int argc, char * argv []) { QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); - arguments.pop_front(); + QString testName = arguments.takeFirst(); + if (!arguments.count()) { - ctkDICOMTesterTest2PrintUsage(); + std::cerr << "Usage: " << qPrintable(testName) + << " [...]" << std::endl; return EXIT_FAILURE; } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMAppWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMAppWidgetTest1.cpp index 1d453f42bf..e3ca4caacd 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMAppWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMAppWidgetTest1.cpp @@ -48,7 +48,13 @@ int ctkDICOMAppWidgetTest1( int argc, char * argv [] ) QCommandLineParser parser; parser.addOption({"I", "Run in interactive mode"}); parser.addPositionalArgument("directory", "Directory to import"); - parser.process(app); + parser.process(app); // Automatically exit if there is a parsing error + + if (parser.positionalArguments().count() != 1) + { + std::cerr << qPrintable(parser.helpText()) << std::endl; + return EXIT_FAILURE; + } QString directoryToImport = parser.positionalArguments().at(0); diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMBrowserTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMBrowserTest1.cpp index abacef0fb0..74ea1c6789 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMBrowserTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMBrowserTest1.cpp @@ -40,12 +40,20 @@ int ctkDICOMBrowserTest1( int argc, char * argv [] ) { QApplication app(argc, argv); - qDebug() << "argc = " << argc; - for (int i = 0; i < argc; ++i) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + bool interactive = arguments.removeOne("-I"); + + if (arguments.count() != 1) { - qDebug() << "\t" << argv[i]; + std::cerr << "Usage: " << qPrintable(testName) + << " [-I] " << std::endl; + return EXIT_FAILURE; } + QString dicomDirectory(arguments.at(0)); + QFileInfo tempFileInfo(QDir::tempPath() + QString("/ctkDICOMBrowserTest1-db")); QString dbDir = tempFileInfo.absoluteFilePath(); qDebug() << "\n\nUsing directory: " << dbDir; @@ -64,7 +72,7 @@ int ctkDICOMBrowserTest1( int argc, char * argv [] ) browser.show(); browser.setDisplayImportSummary(false); - qDebug() << "Importing directory " << argv[1]; + qDebug() << "Importing directory " << dicomDirectory; // [Deprecated] // make sure copy/link dialog doesn't pop up, always copy on import @@ -77,7 +85,7 @@ int ctkDICOMBrowserTest1( int argc, char * argv [] ) // [/Deprecated] // Test import of a few specific files - QDirIterator it(argv[1], QStringList() << "*.IMA", QDir::Files, QDirIterator::Subdirectories); + QDirIterator it(dicomDirectory, QStringList() << "*.IMA", QDir::Files, QDirIterator::Subdirectories); // Skip a few files it.next(); it.next(); @@ -99,7 +107,7 @@ int ctkDICOMBrowserTest1( int argc, char * argv [] ) CHECK_INT(browser.seriesAddedDuringImport(), 1); CHECK_INT(browser.instancesAddedDuringImport(), 3); - browser.importDirectories(QStringList() << argv[1]); + browser.importDirectories(QStringList() << dicomDirectory); browser.waitForImportFinished(); qDebug() << "\n\nAdded to database directory: " << files; @@ -116,7 +124,7 @@ int ctkDICOMBrowserTest1( int argc, char * argv [] ) qDebug() << "\n\nAdded to database directory: " << dbDir; - if (argc <= 2 || QString(argv[argc - 1]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMDirectoryListWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMDirectoryListWidgetTest1.cpp index cfe36d991b..9a05dd2e22 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMDirectoryListWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMDirectoryListWidgetTest1.cpp @@ -33,6 +33,12 @@ int ctkDICOMDirectoryListWidgetTest1( int argc, char * argv [] ) { QApplication app(argc, argv); + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + + bool interactive = arguments.removeOne("-I"); + ctkDICOMDatabase database; ctkDICOMDirectoryListWidget listWidget; listWidget.setDICOMDatabase(0); @@ -42,7 +48,7 @@ int ctkDICOMDirectoryListWidgetTest1( int argc, char * argv [] ) listWidget.show(); - if (argc <= 1 || QString(argv[1]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImageTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImageTest1.cpp index 6fdadb4d5a..ff766c61d1 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImageTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImageTest1.cpp @@ -21,6 +21,7 @@ // Qt includes #include +#include #include @@ -38,14 +39,22 @@ int ctkDICOMImageTest1( int argc, char * argv [] ) { QApplication app(argc, argv); - if (argc <= 1) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + bool interactive = arguments.removeOne("-I"); + + if (arguments.count() != 1) { std::cerr << "Warning, no dicom file given. Test stops" << std::endl; - std::cerr << "Usage: qctkDICOMImageTest1 " << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " [-I] " << std::endl; return EXIT_FAILURE; } - DicomImage dcmtkImage(argv[1]); + QString dicomFilePath(arguments.at(0)); + + DicomImage dcmtkImage(QDir::toNativeSeparators(dicomFilePath).toUtf8()); ctkDICOMImage ctkImage(&dcmtkImage); QLabel qtImage; @@ -58,7 +67,7 @@ int ctkDICOMImageTest1( int argc, char * argv [] ) qtImage.setPixmap(pixmap); qtImage.show(); - if (argc > 2 && QString(argv[2]) == "-I") + if (interactive) { return app.exec(); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImportWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImportWidgetTest1.cpp index d1ad2ebfdd..ed484f2660 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImportWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMImportWidgetTest1.cpp @@ -36,13 +36,19 @@ int ctkDICOMImportWidgetTest1( int argc, char * argv [] ) { QApplication app(argc, argv); + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + + bool interactive = arguments.removeOne("-I"); + ctkDICOMDatabase* database = new ctkDICOMDatabase; ctkDICOMImportWidget importWidget; importWidget.setDICOMDatabase(QSharedPointer(database)); importWidget.setTopDirectory(QDir::tempPath()); importWidget.show(); - if (argc <= 1 || QString(argv[1]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMItemViewTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMItemViewTest1.cpp index 8f75fcf35e..2e6cc8ab4f 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMItemViewTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMItemViewTest1.cpp @@ -40,13 +40,22 @@ int ctkDICOMItemViewTest1( int argc, char * argv [] ) { QApplication app(argc, argv); - if (argc < 2) + + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + bool interactive = arguments.removeOne("-I"); + + if (arguments.count() != 1) { - std::cerr << "Usage: ctkDICOMItemViewTest1 dcmimage [-I]" << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " [-I] " << std::endl; return EXIT_FAILURE; } - DicomImage img(argv[1]); + QString dicomFilePath(arguments.at(0)); + + DicomImage img(QDir::toNativeSeparators(dicomFilePath).toUtf8()); QImage image; QImage image2(200, 200, QImage::Format_RGB32); @@ -60,7 +69,7 @@ int ctkDICOMItemViewTest1( int argc, char * argv [] ) datasetView.update( true, true); datasetView.show(); - if (argc <= 2 || QString(argv[2]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMListenerWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMListenerWidgetTest1.cpp index 0c7632e113..880ccb9b70 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMListenerWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMListenerWidgetTest1.cpp @@ -32,10 +32,16 @@ int ctkDICOMListenerWidgetTest1( int argc, char * argv [] ) { QApplication app(argc, argv); + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + + bool interactive = arguments.removeOne("-I"); + ctkDICOMListenerWidget listenerWidget; listenerWidget.show(); - if (argc <= 1 || QString(argv[1]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMModelTest2.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMModelTest2.cpp index 4e8fe22fe5..7591a4332a 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMModelTest2.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMModelTest2.cpp @@ -46,22 +46,32 @@ int ctkDICOMModelTest2( int argc, char * argv [] ) { QApplication app(argc, argv); - if (argc <= 2) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + bool interactive = arguments.removeOne("-I"); + + if (arguments.count() != 2) { std::cerr << "Warning, no sql file given. Test stops" << std::endl; - std::cerr << "Usage: qctkDICOMModelTest1 " << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } + QString databaseFile(arguments.at(0)); + QString sqlFileName(arguments.at(1)); + try { - ctkDICOMDatabase myCTK( argv[1] ); + ctkDICOMDatabase myCTK(databaseFile); - if (!myCTK.initializeDatabase(argv[2])) - { - std::cerr << "Error when initializing the data base: " << argv[2] - << " error: " << myCTK.lastError().toStdString(); - } + if (!myCTK.initializeDatabase(sqlFileName.toUtf8())) + { + std::cerr << "Error when initializing the data base: " << qPrintable(sqlFileName) + << " error: " << qPrintable(myCTK.lastError()) << std::endl; + return EXIT_FAILURE; + } ctkDICOMModel model; model.setDatabase(myCTK.database()); @@ -85,16 +95,18 @@ int ctkDICOMModelTest2( int argc, char * argv [] ) model.setHeaderData(0, Qt::Horizontal, static_cast(Qt::Checked), Qt::CheckStateRole); qDebug() << "new: " << headerView->isHidden(); topLevel.show(); - if (argc <= 3 || QString(argv[3]) != "-I") + + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } + return app.exec(); } catch (const std::exception& e) { - std::cerr << "Error when opening the data base file: " << argv[1] - << " error: " << e.what(); + std::cerr << "Error when opening the data base file: " << qPrintable(databaseFile) + << " error: " << e.what() << std::endl; return EXIT_FAILURE; } } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMObjectModelTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMObjectModelTest1.cpp index 5134e57a8a..07c19b334f 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMObjectModelTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMObjectModelTest1.cpp @@ -37,10 +37,33 @@ int ctkDICOMObjectModelTest1( int argc, char * argv [] ) { QApplication app(argc, argv); + + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + + bool interactive = arguments.removeOne("-I"); + QString fileName; - //TODO: Add the option for reading the test file from argv - fileName = QFileDialog::getOpenFileName( 0, - "Choose a DCM File", ".","DCM (*)" ); + + if (!interactive && arguments.count() != 1) + { + std::cerr << "Usage: " << qPrintable(testName) + << " [-I] " << std::endl; + return EXIT_FAILURE; + } + + if (arguments.count() == 1) + { + fileName = arguments.at(0); + } + + if (interactive && arguments.count() == 0) + { + fileName = QFileDialog::getOpenFileName( + 0, "Choose a DCM File", ".","DCM (*)" ); + } + ctkDICOMObjectModel dcmObjModel; dcmObjModel.setFile(fileName); @@ -56,5 +79,10 @@ int ctkDICOMObjectModelTest1( int argc, char * argv [] ) viewer->show(); viewer->raise(); + if (!interactive) + { + QTimer::singleShot(200, &app, SLOT(quit())); + } + return app.exec(); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryResultsTabWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryResultsTabWidgetTest1.cpp index 95b7af736a..ede041ffdb 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryResultsTabWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryResultsTabWidgetTest1.cpp @@ -32,11 +32,17 @@ int ctkDICOMQueryResultsTabWidgetTest1( int argc, char * argv [] ) { QApplication app(argc, argv); + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + + bool interactive = arguments.removeOne("-I"); + ctkDICOMQueryResultsTabWidget widget; widget.disableCloseOnTab(0); widget.show(); - if (argc <= 1 || QString(argv[1]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryRetrieveWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryRetrieveWidgetTest1.cpp index d05f48f9e7..16de3e9835 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryRetrieveWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMQueryRetrieveWidgetTest1.cpp @@ -33,6 +33,12 @@ int ctkDICOMQueryRetrieveWidgetTest1( int argc, char * argv [] ) { QApplication app(argc, argv); + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + + bool interactive = arguments.removeOne("-I"); + QSharedPointer dicomDatabase; ctkDICOMQueryRetrieveWidget widget; widget.setRetrieveDatabase(dicomDatabase); @@ -40,13 +46,14 @@ int ctkDICOMQueryRetrieveWidgetTest1( int argc, char * argv [] ) { std::cerr << "ctkDICOMQueryRetrieveDatabase::setRetrieveDatabase failed." << std::endl; + return EXIT_FAILURE; } widget.query(); widget.retrieve(); widget.show(); - if (argc <= 1 || QString(argv[1]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMServerNodeWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMServerNodeWidgetTest1.cpp index 01bb5658be..4cd9c76183 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMServerNodeWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMServerNodeWidgetTest1.cpp @@ -33,6 +33,12 @@ int ctkDICOMServerNodeWidgetTest1( int argc, char * argv [] ) { QApplication app(argc, argv); + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + Q_UNUSED(testName); + + bool interactive = arguments.removeOne("-I"); + ctkDICOMServerNodeWidget widget; if (widget.callingAETitle() != "FINDSCU") { @@ -140,7 +146,7 @@ int ctkDICOMServerNodeWidgetTest1( int argc, char * argv [] ) widget.readSettings(); widget.show(); - if (argc <= 1 || QString(argv[1]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMThumbnailListWidgetTest1.cpp b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMThumbnailListWidgetTest1.cpp index 3ecf2f5f4e..b3160e3c4c 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMThumbnailListWidgetTest1.cpp +++ b/Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMThumbnailListWidgetTest1.cpp @@ -35,23 +35,33 @@ int ctkDICOMThumbnailListWidgetTest1( int argc, char * argv [] ) { QApplication app(argc, argv); - if (argc <= 2) + QStringList arguments = app.arguments(); + QString testName = arguments.takeFirst(); + + bool interactive = arguments.removeOne("-I"); + + if (arguments.count() != 2) { std::cerr << "Warning, no sql file given. Test stops" << std::endl; - std::cerr << "Usage: qctkDICOMModelTest1 " << std::endl; + std::cerr << "Usage: " << qPrintable(testName) + << " " << std::endl; return EXIT_FAILURE; } + QString databaseFile(arguments.at(0)); + QString sqlFileName(arguments.at(1)); + try { QFileInfo databasePath; - databasePath.setFile(argv[1]); + databasePath.setFile(databaseFile); ctkDICOMDatabase myCTK( databasePath.absoluteFilePath() ); - if (!myCTK.initializeDatabase(argv[2])) + if (!myCTK.initializeDatabase(sqlFileName.toUtf8())) { - std::cerr << "Error when initializing the data base: " << argv[2] - << " error: " << myCTK.lastError().toStdString(); + std::cerr << "Error when initializing the data base: " << qPrintable(sqlFileName) + << " error: " << qPrintable(myCTK.lastError()) << std::endl; + return EXIT_FAILURE; } ctkDICOMModel model; @@ -62,7 +72,7 @@ int ctkDICOMThumbnailListWidgetTest1( int argc, char * argv [] ) widget.addThumbnails(model.index(0,0)); widget.show(); - if (argc <= 3 || QString(argv[3]) != "-I") + if (!interactive) { QTimer::singleShot(200, &app, SLOT(quit())); } diff --git a/Libs/Widgets/Testing/Cpp/ctkFileDialogTest1.cpp b/Libs/Widgets/Testing/Cpp/ctkFileDialogTest1.cpp index fac117b92f..a0187446d2 100644 --- a/Libs/Widgets/Testing/Cpp/ctkFileDialogTest1.cpp +++ b/Libs/Widgets/Testing/Cpp/ctkFileDialogTest1.cpp @@ -87,10 +87,7 @@ int ctkFileDialogTest1(int argc, char * argv [] ) {"I", "Run in interactive mode"}, {"do-not-use-native-dialogs", "Do not use native dialogs"}, }); - parser.process(app); - - QStringList arguments = app.arguments(); - arguments.pop_front(); // remove application name + parser.process(app); // Automatically exit if there is a parsing error bool skipNativeDialogs = parser.isSet("do-not-use-native-dialogs"); QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, skipNativeDialogs); From 0ae6d191e8346b529e85d36d19926c029897dde0 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 18 Jan 2024 00:57:14 -0500 Subject: [PATCH 3/5] BUG: Set test resource lock on all tests using "dcmqrscp" executable This will prevent the following test from all running in parallel with a `dcmqrscp` executable configured to listen on the same port. Tests either using "dcmqrscp" executable directly or through the `ctkDICOMTester` helper class: * ctkDICOMApplicationTest1 * ctkDICOMQueryTest2 * ctkDICOMRetrieveTest2 * ctkDICOMTesterTest1 * ctkDICOMTesterTest2 --- Applications/Testing/Cpp/CMakeLists.txt | 3 +++ Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/Applications/Testing/Cpp/CMakeLists.txt b/Applications/Testing/Cpp/CMakeLists.txt index 99fa834b00..56668fbce8 100644 --- a/Applications/Testing/Cpp/CMakeLists.txt +++ b/Applications/Testing/Cpp/CMakeLists.txt @@ -66,4 +66,7 @@ if(CTK_APP_ctkDICOMQuery AND CTK_APP_ctkDICOMRetrieve) ) set_property(TEST ${testname} PROPERTY ENVIRONMENT_MODIFICATION "${CTK_TEST_LAUNCH_BUILD_ENVIRONMENT_MODIFICATION}") + + set_property(TEST ${testname} PROPERTY RESOURCE_LOCK "dcmqrscp") + endif() diff --git a/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt b/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt index 9fbbcac6e9..c5106c7884 100644 --- a/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt +++ b/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt @@ -59,6 +59,7 @@ SIMPLE_TEST( ctkDICOMQueryTest2 ${CTKData_DIR}/Data/DICOM/MRHEAD/000055.IMA ${CTKData_DIR}/Data/DICOM/MRHEAD/000056.IMA ) +set_property(TEST "ctkDICOMQueryTest2" PROPERTY RESOURCE_LOCK "dcmqrscp") # ctkDICOMRetrieve SIMPLE_TEST( ctkDICOMRetrieveTest1) @@ -66,6 +67,7 @@ SIMPLE_TEST( ctkDICOMRetrieveTest2 ${CTKData_DIR}/Data/DICOM/MRHEAD/000055.IMA ${CTKData_DIR}/Data/DICOM/MRHEAD/000056.IMA ) +set_property(TEST "ctkDICOMRetrieveTest2" PROPERTY RESOURCE_LOCK "dcmqrscp") # ctkDICOMCore SIMPLE_TEST( ctkDICOMCoreTest1 @@ -75,7 +77,9 @@ SIMPLE_TEST( ctkDICOMCoreTest1 # ctkDICOMTester SIMPLE_TEST( ctkDICOMTesterTest1 ) +set_property(TEST "ctkDICOMTesterTest1" PROPERTY RESOURCE_LOCK "dcmqrscp") SIMPLE_TEST( ctkDICOMTesterTest2 ${CTKData_DIR}/Data/DICOM/MRHEAD/000055.IMA ${CTKData_DIR}/Data/DICOM/MRHEAD/000056.IMA ) +set_property(TEST "ctkDICOMTesterTest2" PROPERTY RESOURCE_LOCK "dcmqrscp") From d49a7a9b08d9df769ff7c970e8f72e5dc4989b9f Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 18 Jan 2024 00:58:37 -0500 Subject: [PATCH 4/5] BUG: Ensure DICOM tests all read/write from different sqlite database --- Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt | 4 ++-- Libs/DICOM/Widgets/Testing/Cpp/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt b/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt index c5106c7884..93829122d4 100644 --- a/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt +++ b/Libs/DICOM/Core/Testing/Cpp/CMakeLists.txt @@ -48,7 +48,7 @@ SIMPLE_TEST(ctkDICOMIndexerTest1 ) # ctkDICOMModel SIMPLE_TEST(ctkDICOMModelTest1 - ${CMAKE_CURRENT_BINARY_DIR}/dicom.db + ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/ctkDICOMModelTest1-dicom.db ${CMAKE_CURRENT_SOURCE_DIR}/../../Resources/dicom-sample.sql ) SIMPLE_TEST(ctkDICOMPersonNameTest1) @@ -71,7 +71,7 @@ set_property(TEST "ctkDICOMRetrieveTest2" PROPERTY RESOURCE_LOCK "dcmqrscp") # ctkDICOMCore SIMPLE_TEST( ctkDICOMCoreTest1 - ${CMAKE_CURRENT_BINARY_DIR}/dicom.db + ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/ctkDICOMCoreTest1-dicom.db ${CMAKE_CURRENT_SOURCE_DIR}/../../Resources/dicom-sample.sql ) diff --git a/Libs/DICOM/Widgets/Testing/Cpp/CMakeLists.txt b/Libs/DICOM/Widgets/Testing/Cpp/CMakeLists.txt index 8434d43437..1430d1a149 100644 --- a/Libs/DICOM/Widgets/Testing/Cpp/CMakeLists.txt +++ b/Libs/DICOM/Widgets/Testing/Cpp/CMakeLists.txt @@ -51,13 +51,13 @@ SIMPLE_TEST(ctkDICOMDirectoryListWidgetTest1) SIMPLE_TEST(ctkDICOMImportWidgetTest1) SIMPLE_TEST(ctkDICOMListenerWidgetTest1) SIMPLE_TEST(ctkDICOMModelTest2 - ${CMAKE_CURRENT_BINARY_DIR}/dicom.db + ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/ctkDICOMModelTest2-dicom.db ${CMAKE_CURRENT_SOURCE_DIR}/../../../Core/Resources/dicom-sample.sql ) SIMPLE_TEST(ctkDICOMQueryRetrieveWidgetTest1) SIMPLE_TEST(ctkDICOMQueryResultsTabWidgetTest1) SIMPLE_TEST(ctkDICOMThumbnailListWidgetTest1 - ${CMAKE_CURRENT_BINARY_DIR}/dicom.db + ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/ctkDICOMThumbnailListWidgetTest1-dicom.db ${CMAKE_CURRENT_SOURCE_DIR}/../../../Core/Resources/dicom-sample.sql ) From 29aae66dcad4d9cd69ba778485eb56636f19bb8d Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 18 Jan 2024 02:09:29 -0500 Subject: [PATCH 5/5] BUG: Update ctkDICOMTester to always kill "storescp" process on destruction Since the DCMTK executable do not seem to configure a termination handler on windows (using `SetConsoleCtrlHandler()`) or on Unix (using `sigaction()`), we speed up testing by simply killing the process. > On Windows, terminate() posts a WM_CLOSE message to all top-level > windows of the process and then to the main thread of the process > itself. On Unix and macOS the SIGTERM signal is sent. > > Console applications on Windows that do not run an event loop, or whose > event loop does not handle the WM_CLOSE message, can only be terminated > by calling kill(). Source: https://doc.qt.io/qt-5/qprocess.html#terminate --- Libs/DICOM/Core/ctkDICOMTester.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Libs/DICOM/Core/ctkDICOMTester.cpp b/Libs/DICOM/Core/ctkDICOMTester.cpp index f6d5d165d0..78c279669f 100644 --- a/Libs/DICOM/Core/ctkDICOMTester.cpp +++ b/Libs/DICOM/Core/ctkDICOMTester.cpp @@ -91,8 +91,10 @@ ctkDICOMTesterPrivate::ctkDICOMTesterPrivate(ctkDICOMTester& o): q_ptr(&o) //------------------------------------------------------------------------------ ctkDICOMTesterPrivate::~ctkDICOMTesterPrivate() { - this->STORESCPProcess->terminate(); - if (!this->STORESCPProcess->waitForFinished()) + // Do not wait for the process to finish. + // See https://doc.qt.io/qt-5/qprocess.html#terminate + // this->STORESCPProcess->terminate(); + // if (!this->STORESCPProcess->waitForFinished()) { this->STORESCPProcess->kill(); }