Mercurial > hg > orthanc
changeset 7121:cf1f10a22505
added test DataSource.SequentialReader
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Fri, 14 Aug 2026 14:57:42 +0200 |
| parents | 0a8b8890f26d |
| children | 22a427e39060 |
| files | OrthancFramework/Sources/DataSource/DataSourceSequentialReader.h OrthancFramework/UnitTestsSources/DataSourceTests.cpp |
| diffstat | 2 files changed, 73 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Sources/DataSource/DataSourceSequentialReader.h Fri Aug 14 13:28:37 2026 +0200 +++ b/OrthancFramework/Sources/DataSource/DataSourceSequentialReader.h Fri Aug 14 14:57:42 2026 +0200 @@ -101,8 +101,10 @@ { } - // Note that "source" will never contain user data, those are handled at the level above - virtual IDynamicObject* Apply(DataSourceAnswer::Item* source) = 0; + // IMPORTANT: The disconnector is in charge of deleting the "source" object. + // If "source" is not properly destructed, deadlock will occur. + // Note that "source" will never contain user data, those are handled at the level above. + virtual IDynamicObject* Apply(DataSourceAnswer::Item* source /* takes ownership */) = 0; }; @@ -126,6 +128,7 @@ void FillWindow(); public: + // IMPORTANT: The "executor" must not be the same as that of "reader", otherwise deadlock will occur DataSourceSequentialReader(const boost::shared_ptr<IExecutorService>& executor, const boost::shared_ptr<DataSourceReader>& reader, IValueDisconnector* disconnector /* takes ownership */,
--- a/OrthancFramework/UnitTestsSources/DataSourceTests.cpp Fri Aug 14 13:28:37 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/DataSourceTests.cpp Fri Aug 14 14:57:42 2026 +0200 @@ -28,6 +28,7 @@ #endif #include "../Sources/DataSource/DataSourceReader.h" +#include "../Sources/DataSource/DataSourceSequentialReader.h" #include "../Sources/MultiThreading/SequentialExecutorService.h" #include "../Sources/MultiThreading/ThreadPool.h" #include "../Sources/OrthancException.h" @@ -128,10 +129,32 @@ return 10; } }; + + + class IntegerDisconnector : public DataSourceSequentialReader::IValueDisconnector + { + public: + virtual IDynamicObject* Apply(DataSourceAnswer::Item* source) ORTHANC_OVERRIDE + { + std::unique_ptr<DataSourceAnswer::Item> protection(source); + + const IntegerIdentifier& id = dynamic_cast<const IntegerIdentifier&>(source->GetId()); + const SingleValueObject<int>& value = dynamic_cast<const SingleValueObject<int>&>(*source->GetValue()); + + if (id.GetValue() != value.GetValue()) + { + throw OrthancException(ErrorCode_InternalError); + } + else + { + return new SingleValueObject<int>(value.GetValue()); + } + } + }; } -TEST(DataSource, Test) +TEST(DataSource, ParallelReader) { boost::shared_ptr<ThreadPool> service(new ThreadPool); service->SetThreadsCount(4); @@ -210,3 +233,47 @@ } } } + + +TEST(DataSource, SequentialReader) +{ + boost::shared_ptr<ThreadPool> serviceSource(new ThreadPool); + serviceSource->SetLoggingThreadName("SOURCE"); + serviceSource->SetThreadsCount(4); + serviceSource->SetDequeueTimeout(5); // Stop the test fast + serviceSource->Start(); + + boost::shared_ptr<ThreadPool> serviceSequential(new ThreadPool); + serviceSequential->SetLoggingThreadName("SEQ"); + serviceSequential->SetThreadsCount(1); + serviceSequential->SetDequeueTimeout(5); // Stop the test fast + serviceSequential->Start(); + + { + boost::shared_ptr<DataSourceReader> reader(new DataSourceReader(serviceSource, new IntegerDataSource)); + + DataSourceSequentialReader seq(serviceSequential, reader, new IntegerDisconnector, 4, 0); + + for (int i = 0; i < 10; i++) + { + seq.Submit(new IntegerIdentifier(false, 10 + i, 10 - i)); // Produces out-of-order values + } + + seq.Start(); + ASSERT_THROW(seq.Submit(new IntegerIdentifier(false, 42, 0)), OrthancException); + + for (int i = 0; i < 10; i++) + { + ASSERT_TRUE(seq.HasNext()); + + std::unique_ptr<DataSourceSequentialReader::Item> item(seq.Next()); + ASSERT_TRUE(item.get() != NULL); + + const SingleValueObject<int>& value = dynamic_cast<const SingleValueObject<int>&>(item->GetValue()); + ASSERT_EQ(10 + i, value.GetValue()); + } + + ASSERT_FALSE(seq.HasNext()); + ASSERT_THROW(seq.Next(), OrthancException); + } +}
