From 542017aa65dc1095c43d1ffa1e7e1910bdfe6fcc Mon Sep 17 00:00:00 2001
From: Ichthyostega
Date: Tue, 13 Jun 2023 20:23:33 +0200
Subject: [PATCH] Dispatcher-Pipeline: mocked Dispatcher implementation
complete (closes: #1294)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`steam/engine/mock-dispatcher.hpp |cpp` now integrates this
''complete mock setup for render jobs and frame dispatching.''
The exising `DummyJob` has been slightly adapted and renamed
to `MockJob` and is tightly integrated with the other mocks.
The implementation of a `MockDispatcher` necessitated to change
the use of `MockJobTicket`. The initial attempts used a complete
mock implementation, but this approach turned out not to be viable.
Instead — based on the ideas developed for the mock setup —
now the prospective real implementation of `JobTicket` is available
and will be used by the mock setup too. Instead of a synthetic spec,
now a setup of recursively connected `ExitNode`(s) is used; the latter
seems to develop into some kind of Facade for the render node network.
Based on this mock setup, we can now demonstrate the (mostly) complete
Job-Planning pipeline, starting from a segmentation up to render jobs,
and verify proper connectivity and job invocation.
✔
---
src/lib/iter-adapter-ptr-deref.hpp | 62 +++----
src/steam/engine/frame-coord.hpp | 1 -
src/steam/engine/job-ticket.hpp | 11 +-
src/steam/fixture/segment.hpp | 1 -
src/steam/fixture/segmentation.hpp | 17 +-
.../{vault => steam}/engine/job-hash-test.cpp | 24 +--
.../steam/engine/job-planning-setup-test.cpp | 31 ++--
.../engine/mock-dispatcher.cpp} | 49 +++---
tests/core/steam/engine/mock-dispatcher.hpp | 151 ++++++++++++------
tests/core/steam/engine/mock-support-test.cpp | 51 +++---
.../engine/scheduler-interface-test.cpp | 12 +-
tests/core/vault/engine/dummy-job.hpp | 75 ---------
wiki/thinkPad.ichthyo.mm | 22 +--
13 files changed, 231 insertions(+), 276 deletions(-)
rename tests/core/{vault => steam}/engine/job-hash-test.cpp (89%)
rename tests/core/{vault/engine/dummy-job.cpp => steam/engine/mock-dispatcher.cpp} (87%)
rename tests/core/{vault => steam}/engine/scheduler-interface-test.cpp (96%)
delete mode 100644 tests/core/vault/engine/dummy-job.hpp
diff --git a/src/lib/iter-adapter-ptr-deref.hpp b/src/lib/iter-adapter-ptr-deref.hpp
index f42a46284..1081b8e3c 100644
--- a/src/lib/iter-adapter-ptr-deref.hpp
+++ b/src/lib/iter-adapter-ptr-deref.hpp
@@ -48,41 +48,11 @@
#include "lib/iter-adapter.hpp"
-#include
+#include
-namespace std {
- template
- class unique_ptr;
-}
-
namespace lib {
- namespace {
-
- /** helper to remove pointer,
- * while retaining const */
- template
- struct RemovePtr { typedef T Type; };
-
- template
- struct RemovePtr { typedef T Type; };
-
- template
- struct RemovePtr { typedef const T Type; };
-
- template
- struct RemovePtr { typedef const T Type; };
-
- template
- struct RemovePtr { typedef const T Type; };
-
- /** allow automatic dereferencing of std::unique_ptr */
- template
- struct RemovePtr> { typedef T Type; };
- }
-
-
/**
* wrapper for an existing Iterator type,
@@ -98,26 +68,30 @@ namespace lib {
public:
- typedef typename IT::value_type pointer;
- typedef typename RemovePtr::Type value_type;
- typedef value_type& reference;
+ /** this iterator adapter is meant to wrap an iterator yielding pointer values */
+ using pointer = typename meta::ValueTypeBinding::value_type;
+ static_assert(std::is_pointer_v);
+
+ using value_type = typename std::remove_pointer_t;
+ using reference = value_type&;
+
ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (PtrDerefIter);
- // the purpose of the following typedefs is to ease building a correct "const iterator"
+ // the purpose of the following typedefs is to support building a correct "const iterator"
- typedef typename boost::remove_const::type ValueTypeBase; // value_type without const
+ using ValueTypeBase = typename std::remove_const_t; // value_type without const
- typedef typename IterType::template SimilarIter< ValueTypeBase* * >::Type WrappedIterType;
- typedef typename IterType::template SimilarIter::Type WrappedConstIterType;
+ using WrappedIterType = typename IterType::template SimilarIter< ValueTypeBase* * >::Type;
+ using WrappedConstIterType = typename IterType::template SimilarIter::Type;
- typedef PtrDerefIter IterType;
- typedef PtrDerefIter ConstIterType;
+ using IterType = PtrDerefIter;
+ using ConstIterType = PtrDerefIter;
- /** PtrDerefIter is always created
+ /** PtrDerefIter is always created
* by wrapping an existing iterator.
*/
explicit
@@ -244,7 +218,7 @@ namespace lib {
- /**
+ /**
* wrapper for an existing Iterator type to expose the address of each value yielded.
* Typically this can be used to build visitation sequences based on values living
* within a stable data structure (e.g. unmodifiable STL vector)
@@ -280,7 +254,7 @@ namespace lib {
ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (AddressExposingIter);
- /** AddressExposingIter is always created
+ /** AddressExposingIter is always created
* by wrapping an existing iterator.
*/
explicit
@@ -304,7 +278,7 @@ namespace lib {
/** @return address of the source iteraor's current result
* @warning exposing a reference to an internal pointer for sake of compatibility.
* Clients must not store that reference, but rather use it to initialise
- * a copy. The internal pointer exposed here will be changed on increment.
+ * a copy. The internal pointer exposed here will be changed on increment.
*/
reference
operator*() const
diff --git a/src/steam/engine/frame-coord.hpp b/src/steam/engine/frame-coord.hpp
index 59285720e..d33d34108 100644
--- a/src/steam/engine/frame-coord.hpp
+++ b/src/steam/engine/frame-coord.hpp
@@ -32,7 +32,6 @@
#include "steam/common.hpp"
#include "steam/mobject/model-port.hpp"
#include "lib/time/timevalue.hpp"
-#include "lib/time/timequant.hpp"
#include
diff --git a/src/steam/engine/job-ticket.hpp b/src/steam/engine/job-ticket.hpp
index 45b3b4c91..14218032f 100644
--- a/src/steam/engine/job-ticket.hpp
+++ b/src/steam/engine/job-ticket.hpp
@@ -36,19 +36,14 @@
#define STEAM_ENGINE_JOB_TICKET_H
#include "steam/common.hpp"
-//#include "steam/state.hpp"
#include "vault/engine/job.h"
#include "steam/engine/frame-coord.hpp"
#include "steam/engine/exit-node.hpp"
-//#include "lib/time/timevalue.hpp"
-//#include "lib/time/timequant.hpp"
#include "lib/hierarchy-orientation-indicator.hpp"
#include "lib/linked-elements.hpp"
+#include "lib/util-foreach.hpp"
#include "lib/iter-adapter.hpp"
#include "lib/itertools.hpp"
-#include "lib/util-foreach.hpp"
-#include "lib/meta/tuple-helper.hpp"
-#include "lib/meta/trait.hpp"
#include "lib/util.hpp"
#include
@@ -58,10 +53,6 @@
namespace steam {
namespace engine {
-//using lib::time::TimeSpan;
-//using lib::time::Duration;
-//using lib::time::FSecs;
-//using lib::time::Time;
using vault::engine::Job;
using vault::engine::JobFunctor;
using vault::engine::JobClosure; /////////////////////////////////////////////////////////////////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs)
diff --git a/src/steam/fixture/segment.hpp b/src/steam/fixture/segment.hpp
index ee10bfc76..469bb54ae 100644
--- a/src/steam/fixture/segment.hpp
+++ b/src/steam/fixture/segment.hpp
@@ -39,7 +39,6 @@
#include "steam/engine/job-ticket.hpp"
#include "lib/allocator-handle.hpp"
#include "lib/time/timevalue.hpp"
-#include "lib/itertools.hpp"
#include "lib/util.hpp"
#include
diff --git a/src/steam/fixture/segmentation.hpp b/src/steam/fixture/segmentation.hpp
index d7ee42c52..4f38551de 100644
--- a/src/steam/fixture/segmentation.hpp
+++ b/src/steam/fixture/segmentation.hpp
@@ -54,6 +54,7 @@
#include
#include
+#include
namespace steam {
@@ -83,19 +84,17 @@ namespace fixture {
class Segmentation
: util::NonCopyable
{
- protected:
/** segments of the engine in ordered sequence. */
list segments_;
- public:
- virtual ~Segmentation(); ///< this is an interface
-
protected:
Segmentation() ///< there is always a single cover-all Segment initially
: segments_{1}
{ }
public:
+ virtual ~Segmentation(); ///< this is an interface
+
size_t
size() const
{
@@ -121,6 +120,16 @@ namespace fixture {
/** rework the existing Segmentation to include a new Segment as specified */
Segment const&
splitSplice (OptTime start, OptTime after, engine::ExitNodes&& modelLink =ExitNodes{});
+
+
+ protected:
+ /** @internal rewrite the NodeGraphAttachment in each Segment */
+ void
+ adaptSpecification (std::function rewrite)
+ {
+ for (fixture::Segment& seg : segments_)
+ seg.exitNode = move(rewrite (seg.exitNode));
+ }
};
diff --git a/tests/core/vault/engine/job-hash-test.cpp b/tests/core/steam/engine/job-hash-test.cpp
similarity index 89%
rename from tests/core/vault/engine/job-hash-test.cpp
rename to tests/core/steam/engine/job-hash-test.cpp
index 26b75a637..ff091b912 100644
--- a/tests/core/vault/engine/job-hash-test.cpp
+++ b/tests/core/steam/engine/job-hash-test.cpp
@@ -29,16 +29,18 @@
#include "lib/util.hpp"
#include "vault/real-clock.hpp"
-#include "vault/engine/dummy-job.hpp"
+#include "steam/engine/mock-dispatcher.hpp"
#include
-namespace vault {
-namespace engine {
-namespace test {
+namespace steam {
+namespace engine{
+namespace test {
using util::isSameObject;
+ using vault::engine::Job;
+ using vault::engine::JobParameter;
@@ -67,23 +69,23 @@ namespace test {
void
verify_simple_job_properties()
{
- Job job = DummyJob::build();
+ MockJob job;
CHECK (job.isValid());
Time beforeInvocation = RealClock::now();
job.triggerJob();
- CHECK (DummyJob::was_invoked (job));
- CHECK (RealClock::now() > DummyJob::invocationTime (job));
- CHECK (beforeInvocation < DummyJob::invocationTime (job));
+ CHECK (MockJob::was_invoked (job));
+ CHECK (RealClock::now() > MockJob::invocationTime (job));
+ CHECK (beforeInvocation < MockJob::invocationTime (job));
}
void
verify_job_identity()
{
- Job job1 = DummyJob::build();
- Job job2 = DummyJob::build();
+ MockJob job1;
+ MockJob job2;
CHECK (job1 != job2, "random test data clash");
@@ -130,4 +132,4 @@ namespace test {
/** Register this test class... */
LAUNCHER(JobHash_test, "unit engine");
-}}} // namespace vault::engine::test
+}}} // namespace steam::engine::test
diff --git a/tests/core/steam/engine/job-planning-setup-test.cpp b/tests/core/steam/engine/job-planning-setup-test.cpp
index 29668e72f..7765e8bb9 100644
--- a/tests/core/steam/engine/job-planning-setup-test.cpp
+++ b/tests/core/steam/engine/job-planning-setup-test.cpp
@@ -28,19 +28,14 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "steam/engine/mock-dispatcher.hpp"
-#include "vault/engine/dummy-job.hpp"
#include "lib/format-cout.hpp"///////////////////////TODO
#include "lib/iter-tree-explorer.hpp"
#include "lib/format-util.hpp"
#include "lib/util.hpp"
-//#include "steam/engine/job-planning.hpp"
-
-//#include
using test::Test;
-//using std::rand;
using lib::eachNum;
using lib::treeExplore;
using lib::time::PQuant;
@@ -52,7 +47,6 @@ namespace steam {
namespace engine{
namespace test {
- using vault::engine::DummyJob;
using lib::time::FixedFrameQuantiser;
namespace { // test fixture...
@@ -83,7 +77,7 @@ namespace test {
* - integration: generate a complete sequence of (dummy)Jobs
* - scaffolding and mocking used for this test
*
- * @todo WIP-WIP-WIP 4/2023
+ * @todo WIP-WIP 4/2023
*
* @see DispatcherInterface_test
* @see MockSupport_test
@@ -112,12 +106,12 @@ namespace test {
Time nominalTime = lib::test::randTime();
int additionalKey = rand() % 5000;
- Job mockJob = DummyJob::build (nominalTime, additionalKey);
+ MockJob mockJob{nominalTime, additionalKey};
mockJob.triggerJob();
- CHECK (DummyJob::was_invoked (mockJob));
- CHECK (RealClock::wasRecently (DummyJob::invocationTime (mockJob)));
- CHECK (nominalTime == DummyJob::invocationNominalTime (mockJob) );
- CHECK (additionalKey == DummyJob::invocationAdditionalKey(mockJob));
+ CHECK (MockJob::was_invoked (mockJob));
+ CHECK (RealClock::wasRecently (MockJob::invocationTime (mockJob)));
+ CHECK (nominalTime == MockJob::invocationNominalTime (mockJob) );
+ CHECK (additionalKey == MockJob::invocationAdditionalKey(mockJob));
// Build a simple Segment at [10s ... 20s[
MockSegmentation mockSegs{MakeRec()
@@ -143,10 +137,15 @@ namespace test {
jobP.triggerJob();
jobM.triggerJob();
- CHECK (123 == DummyJob::invocationAdditionalKey (jobM)); // verify each job was invoked and linked to the correct spec,
- CHECK (555 == DummyJob::invocationAdditionalKey (jobP)); // indicating that in practice it will activate the proper render node
- //
- ////////////////////////////////////////////////////////////////////TODO: extract Dispatcher-Mock from DispatcherInterface_test
+ CHECK (123 == MockJob::invocationAdditionalKey (jobM)); // verify each job was invoked and linked to the correct spec,
+ CHECK (555 == MockJob::invocationAdditionalKey (jobP)); // indicating that in practice it will activate the proper render node
+
+ coord.modelPortIDX = 1;
+ coord.absoluteNominalTime = Time{0,30};
+ MockDispatcher dispatcher; // a complete dispatcher backed by a mock Segment for the whole timeline
+ auto [port1,sink1] = dispatcher.getDummyConnection(1); // also some fake ModelPort and DataSink entries are registered
+ Job jobD = dispatcher.getJobTicketFor(coord).createJobFor(coord);
+ CHECK (dispatcher.verify(jobD, port1, sink1)); // the generated job uses the associated ModelPort and DataSink and JobTicket
}
diff --git a/tests/core/vault/engine/dummy-job.cpp b/tests/core/steam/engine/mock-dispatcher.cpp
similarity index 87%
rename from tests/core/vault/engine/dummy-job.cpp
rename to tests/core/steam/engine/mock-dispatcher.cpp
index 0bc6bff62..a0fa87dfb 100644
--- a/tests/core/vault/engine/dummy-job.cpp
+++ b/tests/core/steam/engine/mock-dispatcher.cpp
@@ -1,5 +1,5 @@
/*
- DummyJob - diagnostic job for unit tests
+ MockDispatcher - diagnostic render job and frame dispatcher
Copyright (C) Lumiera.org
2013, Hermann Vosseler
@@ -20,7 +20,7 @@
* *****************************************************/
-/** @file dummy-job.cpp
+/** @file mock-dispatcher.cpp
** Implementation of a dummy render job for unit tests.
** Based on using a specifically rigged DummyClosure as JobFunctor,
** where the actual Job invocation does nothing other than storing
@@ -32,14 +32,14 @@
**
** # Usage front-end
**
- ** The static functions in vault::engine::DummyJob allow to
- ** - build such a mock job, possibly with random (or well defined) parameters
- ** - when passing back this job instance, verify invocation and extract data
+ ** A MockJob can directly created, and then sliced down to the Job baseclass,
+ ** since it has no additional data fields. The static functions in MockJob allow
+ ** to verify that a given job instance was created from this setup, that it was
+ ** invoked, and verify invocation time and extract data
*/
-#include "vault/engine/dummy-job.hpp"
-
+#include "steam/engine/mock-dispatcher.hpp"
#include "vault/engine/nop-job-functor.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/time/timevalue.hpp"
@@ -50,14 +50,15 @@
#include "lib/util.hpp"
#include
-#include
#include
+#include
-namespace vault{
-namespace engine {
+namespace steam {
+namespace engine{
+namespace test {
- namespace { // DummyJob implementation details...
+ namespace { // MockJob and DummyClosure implementation details...
using lib::HashVal;
using lib::NullValue;
@@ -65,14 +66,16 @@ namespace engine {
using std::unordered_map;
using util::access_or_default;
+ using vault::engine::JobParameter;
+
const int MAX_PARAM_A(1000); ///< random test values 0...1000
const int MAX_PARAM_B(10); ///< random test values -10...+10
/**
- * test dummy jobs are backed by this closure.
- * DummyJob invocations are recorded in a hashtable
+ * MockJob objects are backed by this closure.
+ * Invocations of this job functor are recorded in a hashtable
* @note as of 5/2023, we use a simplistic map-based implementation,
* causing a consecutive invocation of the same job instance
* with identical JobParameter to overwrite the previous log entry.
@@ -158,7 +161,7 @@ namespace engine {
{ }
};
- /** recording DummyJob invocations */
+ /** recording MockJob invocations */
unordered_map invocationLog_;
@@ -195,7 +198,7 @@ namespace engine {
Job
- DummyJob::build()
+ MockJob::build()
{
InvocationInstanceID invoKey;
invoKey.part.a = rand() % MAX_PARAM_A;
@@ -208,7 +211,7 @@ namespace engine {
Job
- DummyJob::build (Time nominalTime, int additionalKey)
+ MockJob::build (Time nominalTime, int additionalKey)
{
InvocationInstanceID invoKey;
invoKey.part.a = additionalKey;
@@ -219,7 +222,7 @@ namespace engine {
bool
- DummyJob::was_invoked (Job const& job)
+ MockJob::was_invoked (Job const& job)
{
REQUIRE (job.usesClosure (dummyClosure));
@@ -228,7 +231,7 @@ namespace engine {
Time
- DummyJob::invocationTime (Job const& job)
+ MockJob::invocationTime (Job const& job)
{
REQUIRE (job.usesClosure (dummyClosure));
@@ -237,7 +240,7 @@ namespace engine {
Time
- DummyJob::invocationNominalTime (Job const& job)
+ MockJob::invocationNominalTime (Job const& job)
{
REQUIRE (job.usesClosure (dummyClosure));
@@ -246,7 +249,7 @@ namespace engine {
int
- DummyJob::invocationAdditionalKey (Job const& job)
+ MockJob::invocationAdditionalKey (Job const& job)
{
REQUIRE (job.usesClosure (dummyClosure));
@@ -256,7 +259,7 @@ namespace engine {
/** @internal for collaboration with other Mock/Dummy facilities */
JobClosure&
- DummyJob::getFunctor()
+ MockJob::getFunctor()
{
return dummyClosure;
}
@@ -268,7 +271,7 @@ namespace engine {
* @see JobTicket::JobTicket::createJobFor(FrameCoord)
*/
bool
- DummyJob::isNopJob (Job const& job)
+ MockJob::isNopJob (Job const& job)
{
InvocationInstanceID empty; ///////////////////////////////////////////////////////////////////////TICKET #1287 : temporary workaround until we get rid of the C base structs
JobClosure& jobFunctor = static_cast (*job.jobClosure); //////////////////////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs)
@@ -278,4 +281,4 @@ namespace engine {
-}} // namespace vault::engine
+}}} // namespace steam::engine::test
diff --git a/tests/core/steam/engine/mock-dispatcher.hpp b/tests/core/steam/engine/mock-dispatcher.hpp
index a0093d298..18996fcb8 100644
--- a/tests/core/steam/engine/mock-dispatcher.hpp
+++ b/tests/core/steam/engine/mock-dispatcher.hpp
@@ -22,19 +22,25 @@
/** @file mock-dispatcher.hpp
** Mock data structures to support implementation testing of render job
- ** planning and frame dispatch. Together with dummy-job.hpp, this provides
- ** a specifically rigged test setup, allowing to investigate and verify
- ** designated functionality in isolation, without backing by the actual
- ** render engine implementation.
- ** - the MockDispatcherTable emulates the frame dispatch from the Fixture
+ ** planning and frame dispatch. This specifically rigged test setup allows to
+ ** investigate and verify designated functionality in isolation, without backing
+ ** by the actual render engine and low-level-Model implementation.
+ ** - a MockJob is a render Job, wired to a DummyFunctor, which does nothing,
+ ** but records any invocation into an internal diagnostics Map.
+ ** - MockJobTicket is a builder / adapter on top of the actual steam::engine::JobTicket,
+ ** allowing to generate simple JobTicket instances with an embedded ExitNode and
+ ** a (configurable) pipelineID. From this setup, »mock jobs« can be generated,
+ ** which use the MockJob functor and thus record any invocation without performing
+ ** actual work. The internal connection to the MockJobTicket can then be verified.
** - MockSegmentation is a mocked variant of the »Segmentation« datastructure,
** which forms the backbone of the Fixture and is the top-level attachment
- ** point for the »low-level-Model« (the render nodes network)
- ** - MockJobTicket is a builder / adapter on top of the actual steam::engine::JobTicket,
- ** allowing to generate a complete rigged MockSegmentation setup from a generic
- ** test specification written as nested lib::diff::GenNode elements. From this
- ** setup, »mock jobs« can be generated, which use the DummyJob functor and
- ** just record any invocation without performing actual work.
+ ** point for the »low-level-Model« (the render nodes network). It can be
+ ** configured with a test specification of ExitNode(s) defined by a
+ ** GenNode tree, and defining Segments of the timeline and prerequisites.
+ ** - finally, the MockDispatcher combines all these facilities to emulate
+ ** frame dispatch from the Fixture without actually using any data model.
+ ** Similar to MockSegmentation, a GenNode-based specification is used.
+ **
** @remark in spring 2023, this setup was created as a means to define and
** then build the actual implementation of frame dispatch and scheduling.
** @see MockSupport_test
@@ -53,7 +59,6 @@
#include "steam/engine/dispatcher.hpp"
#include "steam/engine/job-ticket.hpp"
#include "vault/engine/job.h"
-#include "vault/engine/dummy-job.hpp"
#include "vault/real-clock.hpp"
#include "lib/allocator-handle.hpp"
#include "lib/time/timevalue.hpp"
@@ -79,45 +84,57 @@ namespace test {
using lib::HashVal;
using util::isnil;
using util::isSameObject;
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1294 : organisation of namespaces / includes??
using fixture::Segmentation;
+ using vault::engine::Job;
+ using vault::engine::JobClosure;
- namespace { // used internally
-
- using play::test::ModelPorts;
- using play::test::PlayTestFrames_Strategy;
- using vault::engine::JobClosure;
- using vault::engine::JobParameter;
- using vault::engine::DummyJob;
-
- using DummyPlaybackSetup = play::test::DummyPlayConnection;
-
-
-
-
- /* ===== specify a mock JobTicket setup for tests ===== */
-
- inline ExitNode
- defineSimpleSpec (HashVal seed = 1+rand())
- {
- return ExitNode{seed
- ,ExitNodes{}
- ,& DummyJob::getFunctor()};
- }
-
- }//(End)internal test helpers....
/**
- * Mock setup for a JobTicket to generate DummyJob invocations.
+ * Mock setup for a render Job with NO action but built-in diagnostics.
+ * Each invocation of such a MockJob will be logged internally
+ * and can be investigated and verified afterwards.
+ */
+ class MockJob
+ : public Job
+ {
+ static Job build(); ///< uses random job definition values
+ static Job build (Time nominalTime, int additionalKey);
+
+ public:
+ MockJob()
+ : Job{build()}
+ { }
+
+ MockJob (Time nominalTime, int additionalKey)
+ : Job{build (nominalTime,additionalKey)}
+ { }
+
+
+ static bool was_invoked (Job const& job);
+ static Time invocationTime (Job const& job);
+ static Time invocationNominalTime (Job const& job);
+ static int invocationAdditionalKey (Job const& job);
+
+ static bool isNopJob (Job const&);
+ static JobClosure& getFunctor();
+ };
+
+
+
+
+
+
+ /**
+ * Mock setup for a JobTicket to generate dummy render Job invocations.
* Implemented as subclass, it provides a specification DSL for tests,
* and is able to probe some otherwise opaque internals of JobTicket.
* Beyond that, MockJobTicket has the same storage size; and behaves
* like the regular JobTicket after construction -- but any Job
* created by JobTicket::createJobFor(FrameCoord) will be wired
- * with the DummyJob functor and can thus be related back to
+ * with the MockJob functor and can thus be related back to
* the test specification setup.
* @see JobPlanningSetup_test
* @see DispatcherInterface_test
@@ -132,6 +149,15 @@ namespace test {
return static_cast&> (*this);
}
+ /** provide a test specification wired to MockJob */
+ static ExitNode
+ defineSimpleSpec (HashVal seed = 1+rand())
+ {
+ return ExitNode{seed
+ ,ExitNodes{}
+ ,& MockJob::getFunctor()};
+ }
+
public:
MockJobTicket()
: JobTicket{defineSimpleSpec(), allocator()}
@@ -157,14 +183,14 @@ namespace test {
* test, by passing a test specification in »GenNode« notation to the
* constructor. This specification defines the segments to create
* and allows to associate a marker number, which can later be
- * verified from the actual DummyJob invocation.
+ * verified from the actual DummyClosure invocation.
* - the ctor accepts a sequence of GenNode elements,
* each corresponding to a segment to created
* - optionally, attributes "start" and "after" can be defined
* to provide the lib::time::Time values of segment start/end
* - in addition, optionally a "mark" attribute can be defined;
* the given integer number will be "hidden" in the job instance
- * hash, and can be [verified](\ref DummyJob::invocationAdditionalKey)
+ * hash, and can be [verified](\ref MockJob::invocationAdditionalKey)
* - the _scope_ of each top-level GenNode may hold a sequence of
* nested nodes corresponding to _prerequisite_ JobTicket instances
* - these can in turn hold further nested prerequisites, and so on
@@ -198,7 +224,7 @@ namespace test {
{
return ExitNode{buildSeed (spec)
,buildPrerequisites (spec)
- ,& DummyJob::getFunctor()};
+ ,& MockJob::getFunctor()};
}
/** @internal helper for MockDispatcher */
@@ -238,8 +264,12 @@ namespace test {
inline void
MockSegmentation::duplicateExitNodeSpec (uint times)
{
- for (fixture::Segment& seg : segments_)
- seg.exitNode = move(fixture::NodeGraphAttachment{ExitNodes{times, seg.exitNode[0]}});
+ using Spec = fixture::NodeGraphAttachment;
+
+ Segmentation::adaptSpecification ([times](Spec const& spec)
+ {
+ return Spec{ExitNodes{times, spec[0]}};
+ });
}
@@ -273,6 +303,28 @@ namespace test {
+ namespace { // used internally by MockDispatcher....
+ using play::test::ModelPorts;
+ using play::test::PlayTestFrames_Strategy;
+
+ using DummyPlaybackSetup = play::test::DummyPlayConnection;
+ }
+
+
+
+ /**
+ * A mocked frame Dispatcher setup without any backing model.
+ * Instantiating such a MockDispatcher will automatically create some fake
+ * model structures and some ModelPort and DisplaySink handles (and thereby
+ * push aside and shadow any existing ModelPort registry).
+ *
+ * The configuration is similar to MockSegmentation, using a test spec
+ * given as GenNode-tree to define Segments of the timeline and possibly
+ * pipeline-IDs and prerequisites. One notable difference is that here
+ * the default ctor always creates a single Segment covering the whole
+ * time axis, and that the ExitNode specification is automatically
+ * duplicated for all faked ModelPort(s).
+ */
class MockDispatcher
: public Dispatcher
{
@@ -285,8 +337,9 @@ namespace test {
const PortIdxMap portIdx_;
public:
- /* == mock Dispatcher implementation == */
+ /* == mock implementation of the Dispatcher interface == */
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 : likely to become obsolete
FrameCoord
locateRelative (FrameCoord const&, FrameCnt frameOffset) override
{
@@ -298,7 +351,7 @@ namespace test {
{
UNIMPLEMENTED ("determine when to finish a planning chunk");
}
-
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 : likely to become obsolete
size_t
resolveModelPort (ModelPort modelPort) override
@@ -319,6 +372,7 @@ namespace test {
}
+ public:
MockDispatcher()
: dummySetup_{}
, mockSeg_{MakeRec().genNode()} // Node: generate a single active Segment to cover all
@@ -368,7 +422,7 @@ namespace test {
TimeValue nominalTime{job.parameter.nominalTime};
size_t portIDX = resolveModelPort (port);
JobTicket& ticket = accessJobTicket (portIDX, nominalTime);
- return isnil (ticket)? DummyJob::isNopJob (job)
+ return isnil (ticket)? MockJob::isNopJob (job)
: MockJobTicket::isAssociated (job, ticket);
}
@@ -388,9 +442,6 @@ namespace test {
}
};
-#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1221
-#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1221
-
}}} // namespace steam::engine::test
#endif /*STEAM_ENGINE_TEST_MOCK_DISPATCHER_H*/
diff --git a/tests/core/steam/engine/mock-support-test.cpp b/tests/core/steam/engine/mock-support-test.cpp
index 6c513f9f1..ae6f21b93 100644
--- a/tests/core/steam/engine/mock-support-test.cpp
+++ b/tests/core/steam/engine/mock-support-test.cpp
@@ -29,7 +29,6 @@
#include "lib/test/test-helper.hpp"
#include "steam/engine/mock-dispatcher.hpp"
#include "vault/engine/nop-job-functor.hpp"
-#include "vault/engine/dummy-job.hpp"
#include "lib/iter-tree-explorer.hpp"
#include "lib/util-tuple.hpp"
#include "lib/util.hpp"
@@ -43,7 +42,6 @@ namespace engine{
namespace test {
using steam::fixture::Segment;
- using vault::engine::DummyJob;
using lib::singleValIterator;
using util::isSameObject;
using util::seqTuple;
@@ -55,6 +53,7 @@ namespace test {
* - creating and invoking mock render jobs
* - a mocked JobTicket, generating mock render jobs
* - configurable test setup for a mocked Segmentation datastructure
+ * - configurable setup of a complete frame Dispatcher
* @see JobPlanningSetup_test
* @see Dispatcher
* @see vault::engine::Job
@@ -95,7 +94,7 @@ namespace test {
CHECK (MockJobTicket::isAssociated (job, ticket));
job.triggerJob();
- CHECK (DummyJob::was_invoked (job));
+ CHECK (MockJob::was_invoked (job));
}
@@ -107,21 +106,21 @@ namespace test {
{
Time nominalTime = lib::test::randTime();
int additionalKey = rand() % 5000;
- Job mockJob = DummyJob::build (nominalTime, additionalKey);
+ MockJob mockJob{nominalTime, additionalKey};
CHECK (mockJob.getNominalTime() == nominalTime);
- CHECK (not DummyJob::was_invoked (mockJob));
+ CHECK (not MockJob::was_invoked (mockJob));
mockJob.triggerJob();
- CHECK (DummyJob::was_invoked (mockJob));
- CHECK (RealClock::wasRecently (DummyJob::invocationTime (mockJob)));
- CHECK (nominalTime == DummyJob::invocationNominalTime (mockJob) );
- CHECK (additionalKey == DummyJob::invocationAdditionalKey(mockJob));
+ CHECK (MockJob::was_invoked (mockJob));
+ CHECK (RealClock::wasRecently (MockJob::invocationTime (mockJob)));
+ CHECK (nominalTime == MockJob::invocationNominalTime (mockJob) );
+ CHECK (additionalKey == MockJob::invocationAdditionalKey(mockJob));
- Time prevInvocation = DummyJob::invocationTime (mockJob);
+ Time prevInvocation = MockJob::invocationTime (mockJob);
mockJob.triggerJob();
- CHECK (prevInvocation < DummyJob::invocationTime (mockJob)); // invoked again, recorded new invocation time
- CHECK (nominalTime == DummyJob::invocationNominalTime (mockJob) ); // all other Job parameter recorded again unaltered
- CHECK (additionalKey == DummyJob::invocationAdditionalKey(mockJob));
+ CHECK (prevInvocation < MockJob::invocationTime (mockJob)); // invoked again, recorded new invocation time
+ CHECK (nominalTime == MockJob::invocationNominalTime (mockJob) ); // all other Job parameter recorded again unaltered
+ CHECK (additionalKey == MockJob::invocationAdditionalKey(mockJob));
}
@@ -182,12 +181,12 @@ namespace test {
Job someJob = ticket.createJobFor(coord); // JobTicket uses, but does not check the time given in FrameCoord
CHECK (someJob.parameter.nominalTime == _raw(coord.absoluteNominalTime));
CHECK (MockJobTicket::isAssociated (someJob, ticket)); // but the generated Job is linked to the Closure backed by the JobTicket
- CHECK (not DummyJob::was_invoked (someJob));
+ CHECK (not MockJob::was_invoked (someJob));
someJob.triggerJob();
- CHECK (DummyJob::was_invoked (someJob));
- CHECK (RealClock::wasRecently (DummyJob::invocationTime (someJob)));
- CHECK (someTime == DummyJob::invocationNominalTime (someJob));
+ CHECK (MockJob::was_invoked (someJob));
+ CHECK (RealClock::wasRecently (MockJob::invocationTime (someJob)));
+ CHECK (someTime == MockJob::invocationNominalTime (someJob));
}
//-----------------------------------------------------------------/// Segmentation with a segment spanning part of the timeline > 10s
{
@@ -214,9 +213,9 @@ namespace test {
CHECK (marker == job.parameter.invoKey.part.a);
job.triggerJob();
- CHECK (DummyJob::was_invoked (job));
- CHECK (RealClock::wasRecently (DummyJob::invocationTime (job)));
- CHECK (marker == DummyJob::invocationAdditionalKey (job)); // DummyClosure is rigged such as to feed back the seed in `part.a`
+ CHECK (MockJob::was_invoked (job));
+ CHECK (RealClock::wasRecently (MockJob::invocationTime (job)));
+ CHECK (marker == MockJob::invocationAdditionalKey (job)); // DummyClosure is rigged such as to feed back the seed in `part.a`
// and thus we can prove this job really belongs to the marked segment
// create another job from the (empty) seg1
job = seg1.jobTicket(0).createJobFor (coord);
@@ -250,7 +249,7 @@ namespace test {
Job job = s2.jobTicket(0).createJobFor(coord);
job.triggerJob();
- CHECK (marker == DummyJob::invocationAdditionalKey (job));
+ CHECK (marker == MockJob::invocationAdditionalKey (job));
}
//-----------------------------------------------------------------/// Segmentation with several segments built in specific order
{
@@ -293,10 +292,10 @@ namespace test {
Job job = segment.jobTicket(0).createJobFor(coord);
job.triggerJob();
- CHECK (DummyJob::was_invoked (job));
- CHECK (RealClock::wasRecently (DummyJob::invocationTime (job)));
+ CHECK (MockJob::was_invoked (job));
+ CHECK (RealClock::wasRecently (MockJob::invocationTime (job)));
- return DummyJob::invocationAdditionalKey (job);
+ return MockJob::invocationAdditionalKey (job);
};
CHECK (2 == probeKey(s1)); // verify all generated jobs are wired back to the correct segment
CHECK (3 == probeKey(s2));
@@ -339,8 +338,8 @@ namespace test {
job1.triggerJob();
job2.triggerJob();
- CHECK (23 == DummyJob::invocationAdditionalKey (job1));
- CHECK (11 == DummyJob::invocationAdditionalKey (job2));
+ CHECK (23 == MockJob::invocationAdditionalKey (job1));
+ CHECK (11 == MockJob::invocationAdditionalKey (job2));
}
//-----------------------------------------------------------------/// a tree of deep nested prerequisites
{
diff --git a/tests/core/vault/engine/scheduler-interface-test.cpp b/tests/core/steam/engine/scheduler-interface-test.cpp
similarity index 96%
rename from tests/core/vault/engine/scheduler-interface-test.cpp
rename to tests/core/steam/engine/scheduler-interface-test.cpp
index 3b3f16f31..c940a4fde 100644
--- a/tests/core/vault/engine/scheduler-interface-test.cpp
+++ b/tests/core/steam/engine/scheduler-interface-test.cpp
@@ -31,7 +31,7 @@
#include "vault/real-clock.hpp"
#include "vault/engine/scheduler-frontend.hpp"
#include "vault/engine/scheduler-diagnostics.hpp"
-#include "vault/engine/dummy-job.hpp"
+#include "steam/engine/mock-dispatcher.hpp"
namespace vault {
@@ -44,6 +44,8 @@ namespace test {
using lib::time::Offset;
using lib::time::FSecs;
+ using steam::engine::test::MockJob;
+
namespace { // test fixture: scheduling a dummy job operation...
@@ -92,7 +94,7 @@ namespace test {
{
SchedulerDiagnostics monitor(scheduler);
- Job job = DummyJob::build();
+ MockJob job;
Time deadline(TEST_START_TIME);
scheduler.startJobTransaction()
@@ -112,8 +114,8 @@ namespace test {
JobTransaction tx = scheduler.startJobTransaction();
- Job job1 = DummyJob::build();
- Job job2 = DummyJob::build();
+ MockJob job1;
+ MockJob job2;
tx.addFreewheeling(job1);
tx.addBackground (job2);
@@ -178,7 +180,7 @@ namespace test {
Time nominalTime(dummyFrameStart(frameNr));
Time deadline(TEST_START_TIME + nominalTime);
- Job job = DummyJob::build(nominalTime, frameNr);
+ MockJob job{nominalTime, frameNr};
currentTx.addJob (deadline, job);
diff --git a/tests/core/vault/engine/dummy-job.hpp b/tests/core/vault/engine/dummy-job.hpp
deleted file mode 100644
index d2828b151..000000000
--- a/tests/core/vault/engine/dummy-job.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- DUMMY-JOB.hpp - diagnostic job for unit tests
-
- Copyright (C) Lumiera.org
- 2013, Hermann Vosseler
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** @file dummy-job.hpp
- ** Unit test helper to generate dummy render jobs.
- ** Render Jobs generated from this setup will not actually perform
- ** any action, other than recording this invocation and the used
- ** parameters into a map table managed behind the scenes. Using
- ** the provided query function, it is possible to probe for such
- ** an invocation and to extract the recorded parameter data.
- **
- ** This setup is used both for stand-alone tests, which just require
- ** "some job", but also as part of a complete hierarchy of mocked
- ** data structures related to frame job dispatch and invocation
- ** @see mock-dispatcher.hpp
- ** @see MockSupport_test
- **
- */
-
-
-#ifndef VAULT_ENGINE_DUMMY_JOB_H
-#define VAULT_ENGINE_DUMMY_JOB_H
-
-
-
-#include "vault/engine/job.h"
-#include "lib/time/timevalue.hpp"
-
-
-namespace vault{
-namespace engine {
-
- using lib::time::Time;
-
-
- /**
- * Test helper: generate test dummy jobs with built-in diagnostics.
- * Each invocation of such a dummy job will be logged internally
- * and can be investigated and verified afterwards.
- */
- struct DummyJob
- {
- static Job build(); ///< uses random job definition values
- static Job build (Time nominalTime, int additionalKey);
-
- static bool was_invoked (Job const& job);
- static Time invocationTime (Job const& job);
- static Time invocationNominalTime (Job const& job);
- static int invocationAdditionalKey (Job const& job);
-
- static JobClosure& getFunctor();
- static bool isNopJob (Job const&);
- };
-
-}} // namespace vault::engine
-#endif
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index ee8d470e9..8c950d1bb 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -70119,7 +70119,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -70128,9 +70128,10 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
+
+
+
@@ -70277,7 +70278,8 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
+
@@ -70316,7 +70318,7 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
@@ -70327,17 +70329,18 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
-
-
+
+
-
+
+
@@ -70379,7 +70382,6 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-