Invocation: provide a fake engine context setup
The purpose of this test is to invoke a Render Node graph using the full service environment as present in the Render Engine. However, for sake of clarity, I do not want to pull up the Engine subsystem, but rather use a local / mocked setup of all the services involved. The node invocation is performed from within a worker thread, to demonstrate integration with the thread-local memory pools. The first simple test case builds and then pulls a source node.
This commit is contained in:
parent
f3dcbfe8b9
commit
70bef00324
6 changed files with 195 additions and 11 deletions
|
|
@ -63,9 +63,7 @@ namespace engine {
|
|||
|
||||
static lib::Depend<EngineCtx> access;
|
||||
|
||||
private:
|
||||
EngineCtx();
|
||||
friend class lib::DependencyFactory<EngineCtx>;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace engine{
|
|||
BufferProvider&
|
||||
EngineFacilities::setupCacheProvider() ////////////////////////////////////////////////////////////////TICKET #1223 : in what ways does client code need to interact with the Frame Cache / Management?
|
||||
{
|
||||
return getNaiveBufferManager();
|
||||
return setupBufferProvider();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ TEST "Proc Node metadata key" NodeMeta_test <<END
|
|||
END
|
||||
|
||||
|
||||
PLANNED "Proc Node operation modes" NodeOpera_test <<END
|
||||
TEST "Proc Node operation modes" NodeOpera_test <<END
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,16 +17,67 @@
|
|||
|
||||
|
||||
#include "test/run.hpp"
|
||||
#include "vault/mem/buffer-provider-setup.hpp"
|
||||
#include "vault/mem/engine-buffer-metadata.hpp"
|
||||
#include "vault/mem/engine-buffer-manager.hpp"
|
||||
#include "vault/mem/local-buffer-stage.hpp"
|
||||
#include "vault/mem/local-buffer-store.hpp"
|
||||
#include "steam/engine/engine-facilities.hpp"
|
||||
#include "steam/engine/node-builder.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "lib/thread.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
#include "test/diagnostic-output.hpp"///////////////TODO
|
||||
|
||||
|
||||
//using std::string;
|
||||
using lib::Thread;
|
||||
using std::this_thread::yield;
|
||||
using std::this_thread::sleep_for;
|
||||
using std::chrono_literals::operator ""us;
|
||||
|
||||
|
||||
namespace steam {
|
||||
namespace engine{
|
||||
namespace test {
|
||||
|
||||
namespace { // ========== Test Setup ==========
|
||||
|
||||
using vault::mem::BufferProviderSetup;
|
||||
using vault::mem::LocalBufferStage;
|
||||
using vault::mem::LocalBufferStore;
|
||||
|
||||
using vault::mem::EngineBufferMetadata;
|
||||
using vault::mem::EngineBufferManager;
|
||||
|
||||
class TestEngineBufferSetup
|
||||
: public BufferProviderSetup
|
||||
, public EngineFacilities
|
||||
{
|
||||
public:
|
||||
TestEngineBufferSetup()
|
||||
: BufferProviderSetup{*this}
|
||||
{ }
|
||||
|
||||
auto buildStage() { return std::make_unique<LocalBufferStage>("NodeOpera_test"); }
|
||||
auto buildStore() { return std::make_unique<LocalBufferStore>(); }
|
||||
|
||||
BufferProvider& setupBufferProvider() override { return *this; }
|
||||
};
|
||||
|
||||
struct TestEngineCtx
|
||||
{
|
||||
// install mock instances for the relevant services
|
||||
lib::DependInject<EngineBufferMetadata>::Local<> metaHub;
|
||||
lib::DependInject<EngineBufferManager>::Local<> globalPool;
|
||||
|
||||
// install a rigged access front-end for the buffer management
|
||||
lib::DependInject<EngineFacilities>::Local<TestEngineBufferSetup> bufferSetup;
|
||||
lib::DependInject<EngineCtx>::Local<EngineCtx> frontEndCtx;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -45,7 +96,79 @@ namespace test {
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
UNIMPLEMENTED ("operate some render nodes as linked together");
|
||||
seedRand();
|
||||
|
||||
invokeSimpleNode();
|
||||
}
|
||||
|
||||
|
||||
/** @test directly invoke a simple source node.
|
||||
* - use the node builder to create a simple node
|
||||
* immediately into the current stack frame
|
||||
* - the processing function feeds a fixed random number
|
||||
* into the given output buffer
|
||||
* - then launch a worker thread to pull this node
|
||||
* - create an output buffer directly from the worker thread
|
||||
* - invoke the single port of the node, which is visible
|
||||
* since it was created before starting the local worker thread
|
||||
* - after the invocation, the fixed random number should have been
|
||||
* placed into the output buffer
|
||||
* - after the worker thread has finished, a single buffer allocation
|
||||
* should have happened; this allocation was sent back automatically
|
||||
* and can be claimed and released by the global buffer manager.
|
||||
*/
|
||||
void
|
||||
invokeSimpleNode()
|
||||
{
|
||||
int randNum{rani()};
|
||||
auto fun = [&](int* buff){ *buff = randNum; };
|
||||
|
||||
TestEngineCtx mockEngine;
|
||||
|
||||
ProcNode node{prepareNode("Test")
|
||||
.preparePort()
|
||||
.invoke("fun()", fun)
|
||||
.completePort()
|
||||
.build()};
|
||||
|
||||
Thread testWorker{[&] /* === directly perform a node invocation === */
|
||||
{
|
||||
BuffHandle buff = EngineCtx::access().mem.lockBufferFor<int> (-55);
|
||||
Time nomTime{Time::ZERO};
|
||||
ProcessKey key{0};
|
||||
uint port{0};
|
||||
|
||||
CHECK (-55 == buff.accessAs<int>());
|
||||
|
||||
// Trigger Node invocation...
|
||||
buff = node.pull (port, buff, nomTime, key);
|
||||
|
||||
CHECK (randNum == buff.accessAs<int>());
|
||||
buff.release();
|
||||
}};
|
||||
|
||||
while (testWorker)
|
||||
yield(); // wait for worker to finish
|
||||
|
||||
// the central services were indeed requested / created
|
||||
CHECK (mockEngine.bufferSetup);
|
||||
CHECK (mockEngine.globalPool);
|
||||
CHECK (mockEngine.metaHub);
|
||||
|
||||
// at least two buffer types registered (one generic for int)
|
||||
CHECK (2 <= mockEngine.metaHub->cntEntries());
|
||||
|
||||
// one buffer was requested...
|
||||
CHECK (1 == watch(*mockEngine.globalPool).numAllocs());
|
||||
|
||||
sleep_for (500us); // additional delay for the local pool's destructor
|
||||
// (which is invoked after the thread has terminated)
|
||||
|
||||
// process and close remaining allocations
|
||||
// sent back by the local pool's destructor...
|
||||
mockEngine.globalPool->processPendingRequests();
|
||||
// now there should be no memory leaks.......
|
||||
CHECK (0 == watch(*mockEngine.globalPool).bytesLeased());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ namespace test {
|
|||
* - the prime goal is to demonstrate correctness, balancing memory demand
|
||||
* mostly through lock-free queues, without loosing any allocation.
|
||||
*/
|
||||
class BufferProviderLoad_test : public Test
|
||||
class BufferProviderLoad_test : public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
|
|
|
|||
|
|
@ -89082,7 +89082,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1685050895873" ID="ID_1305413793" MODIFIED="1686789885547" TEXT="JobTicket �� JobFunctor"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685050903817" ID="ID_1951219397" MODIFIED="1714778577842">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685050903817" ID="ID_1951219397" MODIFIED="1782318913646">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -89095,6 +89095,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#3e6184" DESTINATION="ID_1951219397" ENDARROW="Default" ENDINCLINATION="-729;116;" ID="Arrow_ID_1252149896" SOURCE="ID_1316148159" STARTARROW="None" STARTINCLINATION="427;24;"/>
|
||||
<linktarget COLOR="#4151b6" DESTINATION="ID_1951219397" ENDARROW="Default" ENDINCLINATION="-224;272;" ID="Arrow_ID_1424052882" SOURCE="ID_426502930" STARTARROW="None" STARTINCLINATION="530;22;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1714777535544" ID="ID_1292334278" MODIFIED="1714777603974" TEXT="nominell-zeitliche Koordinate">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -91082,9 +91083,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1718840198722" ID="ID_821758494" MODIFIED="1736101710239" TEXT="Fazit (1:N)">
|
||||
<node CREATED="1718840198722" ID="ID_821758494" MODIFIED="1782318901343" TEXT="Fazit (1:N)">
|
||||
<linktarget COLOR="#77274c" DESTINATION="ID_821758494" ENDARROW="Default" ENDINCLINATION="-254;66;" ID="Arrow_ID_474260214" SOURCE="ID_811413379" STARTARROW="None" STARTINCLINATION="811;-49;"/>
|
||||
<linktarget COLOR="#6c5499" DESTINATION="ID_821758494" ENDARROW="Default" ENDINCLINATION="-305;510;" ID="Arrow_ID_1100764489" SOURCE="ID_290743732" STARTARROW="None" STARTINCLINATION="891;35;"/>
|
||||
<linktarget COLOR="#462f81" DESTINATION="ID_821758494" ENDARROW="Default" ENDINCLINATION="-497;447;" ID="Arrow_ID_1332141638" SOURCE="ID_426502930" STARTARROW="None" STARTINCLINATION="827;34;"/>
|
||||
<node CREATED="1718840201860" ID="ID_589597825" MODIFIED="1718840211116" TEXT="die ExitNode bekommt eine neue Rolle"/>
|
||||
<node CREATED="1718840212128" ID="ID_815017645" MODIFIED="1718840220877" TEXT="...nämlich genau dieses Mapping zu leisten">
|
||||
<node CREATED="1718840222671" ID="ID_965571589" MODIFIED="1718840253430" TEXT="high-Level ggfs strukturierte Model-Ports"/>
|
||||
|
|
@ -98868,6 +98870,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1782263611891" ID="ID_714205556" LINK="#ID_462733128" MODIFIED="1782263644973" TEXT="werde wohl dafür einen Unit-Test zum Aufbau brauchen"/>
|
||||
<node CREATED="1782318712259" ID="ID_426502930" MODIFIED="1782319131757" TEXT="für die Job-Invocation notwendige Parameter / Freiheitsgrade beachten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Hier besteht ein »bottleneck« — insofern wir sparsam mit dem Speicher in den Segmenten und der Job-Activity-Language umgehen müssen; möglicherweise lassen sich gewisse (theoretische) Freiheitsgrade zusammenfalten in eine Processing-ID, an die ein Mapping gebunden wird (⟶ Stream-Types, Ausführungs-Zustand, Switchboard). Letztlich wird das aber über mehrere Stufen heruntergebrochen, so daß beim Einstieg in den jeweiligen Node-Pull eigentlich alle Freiheitsgrade und Parameter disjunkt vorliegen sollten...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#4151b6" DESTINATION="ID_1951219397" ENDARROW="Default" ENDINCLINATION="-224;272;" ID="Arrow_ID_1424052882" STARTARROW="None" STARTINCLINATION="530;22;"/>
|
||||
<arrowlink COLOR="#462f81" DESTINATION="ID_821758494" ENDARROW="Default" ENDINCLINATION="-497;447;" ID="Arrow_ID_1332141638" STARTARROW="None" STARTINCLINATION="827;34;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1782263447684" ID="ID_271895917" MODIFIED="1782263470602" TEXT="muß durch Prototyping herausfinden was der »darunterliegende Code« braucht"/>
|
||||
<node CREATED="1782263496601" ID="ID_304797502" MODIFIED="1782263511901" TEXT="muß diese Bestandteile im Test-Setup zum Laufen bekommen"/>
|
||||
|
|
@ -116661,9 +116678,52 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1780347617296" ID="ID_1297498308" MODIFIED="1780347628941" TEXT="Ausgabe per OutputSlot"/>
|
||||
<node CREATED="1780347660957" ID="ID_664296230" MODIFIED="1780347671228" TEXT="Nodes vorher per NodeBuilder aufbauen"/>
|
||||
</node>
|
||||
<node CREATED="1780347599733" ID="ID_1443629697" MODIFIED="1780347610216" TEXT="aber grundsätzlich noch die Test-Variante"/>
|
||||
<node CREATED="1780347599733" ID="ID_1443629697" MODIFIED="1782339989101" TEXT="aber Services direkt instantiieren (nicht die »echte Engine«)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Das möchte ich so halten zur Dokumentation der Zusammenhänge; hier geht es um Komponenten-Integration — nicht um einen Systemtest. Teils werden jedoch bereits die gleichen Komponenten verwendet, wie in der »echten Engine«, vor allem der BufferProvider mit lokalen Pools. Andererseits werden die RenderNodes noch direkt erzeugt.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node COLOR="#2a7b8f" CREATED="1782348968435" ID="ID_1373429853" MODIFIED="1782349068032" TEXT="Trick: verwende spezielle EngineFacilities">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
diese Subklasse ist zugleich ein BufferProviderSetup, und etabliert damit auch das Schema mit den local-mem-pools
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1782349073329" ID="ID_1059252137" MODIFIED="1782349264675" TEXT="muß dafür aber den EngineCtx als Mock instantiieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...ich wollte diese direkten Referenz-Felder, um im produktiven Einsatz mir jeweils eine Indirektion einzusparen ⟹ das hat die Konsequenz, daß ich auch eine neue Instanz des EngineCtx (als front-End) erzeugen muß, um eine spezielle lokale Instanz des BufferProviderSetup injizieren zu können. Deshalb muß EngineCtx dann doch public konstruierbar sein (und nicht private mit fried für die DependencyFactory). Schade, aber letztlich irrelevant.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1733527376977" ID="ID_506164017" MODIFIED="1733527393014" TEXT="typische Kollaborations-Schemata">
|
||||
<node COLOR="#338800" CREATED="1782348916436" ID="ID_1779017226" MODIFIED="1782348932939" TEXT="erst mal eine einfache source-Node aufrufen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1742172669058" ID="ID_1246173489" MODIFIED="1742172669058" TEXT="Job ruft 2-Node-Chain auf (incl Buffer-Management)">
|
||||
<linktarget COLOR="#01c3fe" DESTINATION="ID_1246173489" ENDARROW="Default" ENDINCLINATION="-1287;-72;" ID="Arrow_ID_1281025448" SOURCE="ID_1063052148" STARTARROW="None" STARTINCLINATION="-777;45;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -116673,13 +116733,16 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node COLOR="#338800" CREATED="1782263969797" ID="ID_1061860304" MODIFIED="1782263998735" TEXT="Prototyping des Node-Pull (�� NodeLink_test)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1782264001438" ID="ID_803942955" MODIFIED="1782264027626" TEXT="diesen Test mit einem tatsächlichen Buffer-Manager betreiben">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1782264001438" ID="ID_803942955" MODIFIED="1782348836995" TEXT="diesen Test mit einem tatsächlichen Buffer-Manager betreiben">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1782264029058" ID="ID_1859274644" MODIFIED="1782264212337" TEXT="Vorbild: BufferProviderLoad_test">
|
||||
<linktarget COLOR="#6d7983" DESTINATION="ID_1859274644" ENDARROW="Default" ENDINCLINATION="1027;88;" ID="Arrow_ID_1323120640" SOURCE="ID_200114754" STARTARROW="None" STARTINCLINATION="1041;-37;"/>
|
||||
</node>
|
||||
<node CREATED="1782264230355" ID="ID_599492347" MODIFIED="1782264244009" TEXT="definiert Setup mit Worker-Thread im Test"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1782348878612" ID="ID_639195897" MODIFIED="1782348912089" TEXT="dann einen Node-Tree aufrufen — mit DiagnosticOutputSlot">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1782264256180" ID="ID_901821600" MODIFIED="1782264427850" TEXT="daraus dann die Bestandteile der NodeInvocation extrahieren">
|
||||
<arrowlink COLOR="#535988" DESTINATION="ID_462733128" ENDARROW="Default" ENDINCLINATION="-21;-42;" ID="Arrow_ID_161274584" STARTARROW="None" STARTINCLINATION="-46;2;"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue