Attempt to fix DummyBuilderContext / DummyPlayConnection
These provide a faked context setup for unit testing. I created them ''out of sheer desperation'' several years ago, since it is impossible to verify the building blocks if you don't know what the building itself will look like. The recent design clean-up of OutputSlot has unfortunately removed a bunch of »hexagonal hooks« — and now I seem to be unable to hook into anything with my tests. Oh my!
This commit is contained in:
parent
eeabbb4f60
commit
b804015cd7
2 changed files with 102 additions and 34 deletions
|
|
@ -37,6 +37,10 @@
|
|||
** _component integration test_ -- yet for this to work, we'd need
|
||||
** - a fake calculation
|
||||
** - a fake OutputSlot
|
||||
** @todo 5/2026 now I have beefed up the OutputSlot so that it can receive
|
||||
** two feeds with an arbitrary number of frames. Still not sure if it's needed;
|
||||
** however it should be noted that the MockDispatcher relies on the DummyPlayConnection,
|
||||
** which in turn uses SimulatedBuilderContext, mostly to get _just some model ports_.
|
||||
**
|
||||
** @see mock-dispatcher.hpp
|
||||
** @see JobPlanningPipeline_test
|
||||
|
|
@ -47,6 +51,8 @@
|
|||
#define STEAM_PLAY_DUMMY_BUILDER_CONTEXT_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "steam/mobject/model-port.hpp"
|
||||
#include "steam/fixture/model-port-registry.hpp"
|
||||
#include "vault/out/output-slot-connection.hpp"
|
||||
|
|
@ -61,11 +67,14 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <array>
|
||||
|
||||
|
||||
namespace steam{
|
||||
namespace play {
|
||||
namespace test {
|
||||
namespace err = lumiera::error;
|
||||
|
||||
using fixture::ModelPortRegistry;
|
||||
using vault::mem::Buff;
|
||||
|
|
@ -73,44 +82,83 @@ namespace test {
|
|||
using vault::out::DataSink;
|
||||
using vault::out::FrameID;
|
||||
using lib::time::TimeValue;
|
||||
using util::_Fmt;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @todo 5/2023 quick-n-dirty placeholder to be able to fabricate fake DataSink handles (`Handle<Connection>`)
|
||||
*/ /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : after the refactoring of OutputSlot 3/2026 it is not that easy any more. We need a Fake OutputSlot
|
||||
class UnimplementedConnection
|
||||
: public vault::out::OutputSlot::Connection
|
||||
{
|
||||
size_t getBufferSize() const override { UNIMPLEMENTED ("getBufferSize()"); }
|
||||
Buff* claimBufferFor (FrameID) override;
|
||||
void publish (Buff*) override { UNIMPLEMENTED ("publish buffer content"); }
|
||||
void release (Buff*) override { UNIMPLEMENTED ("complete buffer cycle"); }
|
||||
void shutDown () override { UNIMPLEMENTED ("shutDown() Connection"); }
|
||||
|
||||
public:
|
||||
~UnimplementedConnection();
|
||||
UnimplementedConnection() = default;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A placeholder/dummy OutputSlot
|
||||
* @todo 5/2026 it can barely be created right now;
|
||||
* A placeholder/dummy OutputSlot that captures all
|
||||
* delivered output data into heap-allocated memory.
|
||||
* @todo 5/2026 it can now be created and allocates a fixed layout
|
||||
* of buffer storage, which implies it should not be copied
|
||||
* and is thus used differently than a real OutputSlot;
|
||||
* should reconsider what is actually needed here!
|
||||
* @warning this used to be placeholder code, and now it was adapted
|
||||
* to store frames, yet this new functionality is untested as of 5/2026
|
||||
*/
|
||||
struct FakeSlot
|
||||
struct FakeOutput
|
||||
: OutputSlot
|
||||
, util::NonCopyable
|
||||
{
|
||||
static constexpr uint NUM_CONNECTIONS = 2;
|
||||
static constexpr uint NUM_FEEDS = 2;
|
||||
static constexpr bool SINGLE_THREADED_TEST = true;
|
||||
using Connections = lib::ScopedCollection<UnimplementedConnection>;
|
||||
using MockConnectState = OutputSlot::AllocState<UnimplementedConnection, SINGLE_THREADED_TEST>;
|
||||
|
||||
FakeSlot()
|
||||
: OutputSlot{std::make_unique<MockConnectState> (NUM_CONNECTIONS, Connections::fill())}
|
||||
using DummyDat = uint64_t;
|
||||
static constexpr size_t DUMMY_BUFF_SIZ = 1_KiB * sizeof(DummyDat);
|
||||
|
||||
using DummyBuff = std::array<DummyDat, DUMMY_BUFF_SIZ>;
|
||||
using DummyBuffSeq = std::deque<DummyBuff>;
|
||||
|
||||
/**
|
||||
* @todo 5/2026 quick-n-dirty placeholder code
|
||||
* to expose some output buffers and provide
|
||||
* the corresponding DataSink handles
|
||||
*/
|
||||
class DummyOutputConnection
|
||||
: public vault::out::OutputSlot::Connection
|
||||
{
|
||||
DummyBuffSeq& buffers_;
|
||||
|
||||
size_t getBufferSize() const override { return DUMMY_BUFF_SIZ; }
|
||||
Buff* claimBufferFor (FrameID) override;
|
||||
void publish (Buff*) override { /* fake "publish buffer content" */ }
|
||||
void release (Buff*) override { /* fake "complete buffer cycle" */ }
|
||||
void shutDown () override { /* fake "shutDown() Connection" */ }
|
||||
|
||||
public:
|
||||
~DummyOutputConnection();
|
||||
DummyOutputConnection (DummyBuffSeq& buffers)
|
||||
: buffers_{buffers}
|
||||
{ }
|
||||
// OutputSlot::Connection is non-copyable
|
||||
};
|
||||
|
||||
using Connections = lib::ScopedCollection<DummyOutputConnection>;
|
||||
using MockConnectState = OutputSlot::AllocState<DummyOutputConnection, SINGLE_THREADED_TEST>;
|
||||
|
||||
using OutBuffs = std::array<DummyBuffSeq, NUM_FEEDS>;
|
||||
OutBuffs buffers_{};
|
||||
|
||||
FakeOutput()
|
||||
: OutputSlot{std::make_unique<MockConnectState> (NUM_FEEDS
|
||||
,[&,i=0](auto& storage) mutable
|
||||
{
|
||||
storage.template create<DummyOutputConnection> (buffers_[i++]);
|
||||
})}
|
||||
{ }
|
||||
};
|
||||
|
||||
inline Buff*
|
||||
FakeOutput::DummyOutputConnection::claimBufferFor (FrameID fra)
|
||||
{
|
||||
REQUIRE (fra >= 0);
|
||||
if (uint64_t(fra) >= buffers_.size())
|
||||
buffers_.resize(fra+10);
|
||||
return reinterpret_cast<Buff*> (& buffers_[fra]);
|
||||
}
|
||||
|
||||
|
||||
using asset::Pipe;
|
||||
using asset::PPipe;
|
||||
using asset::Struct;
|
||||
|
|
@ -159,6 +207,8 @@ namespace test {
|
|||
std::vector<ModelPort> modelPorts_;
|
||||
std::vector<DataSink> dataSinks_;
|
||||
|
||||
FakeOutput fakeOutput_;
|
||||
|
||||
/** setup */
|
||||
SimulatedBuilderContext()
|
||||
: registry_()
|
||||
|
|
@ -194,11 +244,9 @@ namespace test {
|
|||
modelPorts_.push_back (ModelPort(pipeB));
|
||||
|
||||
// prepare corresponding placeholder DataSink (a fake active output connection)
|
||||
FakeSlot fakeSlot;
|
||||
dataSinks_.clear();
|
||||
lib::explore(fakeSlot.getOpenedSinks())
|
||||
lib::explore(fakeOutput_.getOpenedSinks())
|
||||
.effuse (dataSinks_);
|
||||
// Note: keeps FakeSlot alive (due to embedded ref-count)...
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -216,12 +264,32 @@ namespace test {
|
|||
,dataSinks_[index]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
inline vault::mem::Buff* UnimplementedConnection::claimBufferFor (FrameID)
|
||||
/**
|
||||
* Access a generated output frame.
|
||||
* @remark FakeOutput maintains Deque-Storage for each feed.
|
||||
* @tparam X data type to assume as content of the frame (only checked for size)
|
||||
* @param feed number of the output feed to access
|
||||
* @param frame frame numer within the output feed
|
||||
*/
|
||||
template<typename X>
|
||||
X&
|
||||
accessOutputBufferAs (uint feed, FrameID frame)
|
||||
{
|
||||
UNIMPLEMENTED ("claimBufferFor(FrameID)");
|
||||
static_assert (sizeof(X) <= FakeOutput::DUMMY_BUFF_SIZ
|
||||
,"desired data type would not fit into FakeOutput buffer");
|
||||
if (feed >= FakeOutput::NUM_FEEDS)
|
||||
throw err::Invalid{_Fmt{"Feed #%i > %i allowed"}
|
||||
% feed % (FakeOutput::NUM_FEEDS-1)};
|
||||
|
||||
auto availFrames = fakeOutput_.buffers_[feed].size();
|
||||
if (frame >= availFrames)
|
||||
throw err::Invalid{_Fmt{"Frame #%02i > %02i available frames"}
|
||||
% frame % availFrames};
|
||||
|
||||
return reinterpret_cast<X&> (fakeOutput_.buffers_[feed][frame]);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace steam::play::test
|
||||
}}} // namespace steam::play::test
|
||||
#endif /*STEAM_PLAY_DUMMY_BUILDER_CONTEXT_H*/
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace test {
|
|||
|
||||
} // (End) hidden service impl details
|
||||
|
||||
UnimplementedConnection::~UnimplementedConnection() { } ///< emit VTable here...
|
||||
FakeOutput::DummyOutputConnection::~DummyOutputConnection() { } ///< emit VTable here...
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue