# HG changeset patch # User Sebastien Jodogne # Date 1786706917 -7200 # Node ID 0a8b8890f26dd188f2fbf868bdcc6792c8339342 # Parent 9bc237efa31a40057aaef6ba70cb54f7a46c0441 unit testing DataSourceReader diff -r 9bc237efa31a -r 0a8b8890f26d OrthancFramework/UnitTestsSources/DataSourceTests.cpp --- a/OrthancFramework/UnitTestsSources/DataSourceTests.cpp Fri Aug 14 12:53:54 2026 +0200 +++ b/OrthancFramework/UnitTestsSources/DataSourceTests.cpp Fri Aug 14 13:28:37 2026 +0200 @@ -27,16 +27,186 @@ # include #endif -#include - #include "../Sources/DataSource/DataSourceReader.h" #include "../Sources/MultiThreading/SequentialExecutorService.h" +#include "../Sources/MultiThreading/ThreadPool.h" #include "../Sources/OrthancException.h" +#include "../Sources/SystemToolbox.h" +#include +#include using namespace Orthanc; -TEST(DataSource, Basic) +namespace { + class IntegerIdentifier : public IDataIdentifier + { + private: + bool fails_; + int value_; + int sleep_; + + public: + IntegerIdentifier(bool fails, + int value, + int sleep) : + fails_(fails), + value_(value), + sleep_(sleep) + { + } + + bool IsFails() const + { + return fails_; + } + + int GetValue() const + { + return value_; + } + + IDynamicObject* Create() const + { + if (sleep_ > 0) + { + SystemToolbox::USleep(1000 * sleep_); + } + + if (fails_) + { + throw OrthancException(ErrorCode_Database /* some random error code */, + "This was value " + boost::lexical_cast(value_)); + } + else + { + return new SingleValueObject(value_); + } + } + + virtual bool GetCacheKey(std::string& key) const ORTHANC_OVERRIDE + { + return false; + } + + virtual bool EstimateValueSize(size_t& target) const ORTHANC_OVERRIDE + { + return false; + } + + virtual bool HasUserData() const ORTHANC_OVERRIDE + { + return false; + } + + virtual const IDynamicObject& GetUserData() const ORTHANC_OVERRIDE + { + throw OrthancException(ErrorCode_InternalError); + } + + virtual IDynamicObject* ReleaseUserData() ORTHANC_OVERRIDE + { + throw OrthancException(ErrorCode_InternalError); + } + }; + + + class IntegerDataSource : public IDataSource + { + public: + virtual IDynamicObject* Load(const IDataIdentifier& identifier, + const boost::shared_ptr& readerCache /* could be NULL */) ORTHANC_OVERRIDE + { + const IntegerIdentifier& id = dynamic_cast(identifier); + return id.Create(); + } + + virtual size_t GetValueSize(const IDynamicObject& value) const ORTHANC_OVERRIDE + { + return 10; + } + }; } + + +TEST(DataSource, Test) +{ + boost::shared_ptr service(new ThreadPool); + service->SetThreadsCount(4); + service->SetDequeueTimeout(5); // Stop the test fast + service->Start(); + + DataSourceReader reader(service, new IntegerDataSource); + + { + std::unique_ptr item(reader.ReadSingle(new IntegerIdentifier(false, 10, 0))); + ASSERT_TRUE(item.get() != NULL); + ASSERT_EQ(10u, dynamic_cast(item->GetId()).GetValue()); + ASSERT_EQ(10u, dynamic_cast&>(*item->GetValue()).GetValue()); + } + + { + std::unique_ptr item(reader.ReadSingle(new IntegerIdentifier(true, 20, 0))); + ASSERT_TRUE(item.get() != NULL); + ASSERT_EQ(20u, dynamic_cast(item->GetId()).GetValue()); + + bool hasThrown = false; + + try + { + dynamic_cast&>(*item->GetValue()).GetValue(); + } + catch (OrthancException& e) + { + hasThrown = true; + ASSERT_EQ(ErrorCode_Database, e.GetErrorCode()); + ASSERT_TRUE(e.HasDetails()); + ASSERT_EQ("This was value 20", std::string(e.GetDetails())); + } + + ASSERT_TRUE(hasThrown); + } + + { + DataSourceReader reader(service, new IntegerDataSource); + + boost::shared_ptr answer; + + { + std::unique_ptr request(new DataSourceRequest); + for (int i = 0; i < 10; i++) + { + request->Enqueue(new IntegerIdentifier(false, 10 + i, 10 - i)); // Produces out-of-order values + } + + answer = reader.Submit(request.release()); + + std::set values; + + while (true) + { + std::unique_ptr item(answer->Dequeue()); + if (item) + { + const IntegerIdentifier& id = dynamic_cast(item->GetId()); + const SingleValueObject& value = dynamic_cast&>(*item->GetValue()); + ASSERT_EQ(id.GetValue(), value.GetValue()); + values.insert(value.GetValue()); + } + else + { + break; + } + } + + ASSERT_EQ(10u, values.size()); + + for (int i = 0; i < 10; i++) + { + ASSERT_TRUE(values.find(10 + i) != values.end()); + } + } + } +}