Doxygen will only process files with a @file documentation comment. Up to now, none of our test code has such a comment, preventing the cross-links to unit tests from working. This is unfortunate, since unit tests, and even the code comments there, can be considered as the most useful form of technical documentation. Thus I'll start an initiative to fill in those missing comments automatically
198 lines
6.3 KiB
C++
198 lines
6.3 KiB
C++
/*
|
|
SchedulerInterface(Test) - verify invocation structure of the scheduler interface
|
|
|
|
Copyright (C) Lumiera.org
|
|
2013, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
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 scheduler-interface-test.cpp
|
|
** unit test §§TODO§§
|
|
*/
|
|
|
|
|
|
#include "lib/test/run.hpp"
|
|
#include "lib/util.hpp"
|
|
|
|
#include "backend/real-clock.hpp"
|
|
#include "backend/engine/scheduler-frontend.hpp"
|
|
#include "backend/engine/scheduler-diagnostics.hpp"
|
|
#include "backend/engine/dummy-job.hpp"
|
|
|
|
|
|
namespace backend {
|
|
namespace engine {
|
|
namespace test {
|
|
|
|
using util::isSameObject;
|
|
|
|
using lib::time::Duration;
|
|
using lib::time::Offset;
|
|
using lib::time::FSecs;
|
|
|
|
|
|
namespace { // test fixture: scheduling a dummy job operation...
|
|
|
|
|
|
Time TEST_START_TIME (backend::RealClock::now());
|
|
const Duration TEST_FRAME_DURATION(FSecs(1,2));
|
|
|
|
inline Offset
|
|
dummyFrameStart (uint frameNr)
|
|
{
|
|
return frameNr * TEST_FRAME_DURATION;
|
|
}
|
|
|
|
} //(End) test fixture
|
|
|
|
|
|
|
|
|
|
|
|
typedef SchedulerFrontend::JobTransaction JobTransaction;
|
|
|
|
|
|
/***********************************************************************//**
|
|
* @test verify and demonstrate the organisation of the high-level interface
|
|
* for defining jobs to be invoked by the scheduler.
|
|
*
|
|
* @see SchedulerFrongend
|
|
* @see DispatcherInterface_test
|
|
*/
|
|
class SchedulerInterface_test : public Test
|
|
{
|
|
|
|
virtual void
|
|
run (Arg)
|
|
{
|
|
SchedulerFrontend& scheduler = SchedulerFrontend::instance();
|
|
|
|
verify_simple_job_specification (scheduler);
|
|
verify_job_specification_variations (scheduler);
|
|
demonstrate_nested_job_specification (scheduler);
|
|
}
|
|
|
|
|
|
void
|
|
verify_simple_job_specification (SchedulerFrontend& scheduler)
|
|
{
|
|
SchedulerDiagnostics monitor(scheduler);
|
|
|
|
Job job = DummyJob::build();
|
|
Time deadline(TEST_START_TIME);
|
|
|
|
scheduler.startJobTransaction()
|
|
.addJob(deadline, job)
|
|
.commit();
|
|
|
|
CHECK ( monitor.is_scheduled_timebound (job));
|
|
CHECK (!monitor.is_scheduled_background (job));
|
|
CHECK (!monitor.is_scheduled_freewheeling (job));
|
|
}
|
|
|
|
|
|
void
|
|
verify_job_specification_variations (SchedulerFrontend& scheduler)
|
|
{
|
|
SchedulerDiagnostics monitor(scheduler);
|
|
|
|
JobTransaction tx = scheduler.startJobTransaction();
|
|
|
|
Job job1 = DummyJob::build();
|
|
Job job2 = DummyJob::build();
|
|
|
|
tx.addFreewheeling(job1);
|
|
tx.addBackground (job2);
|
|
|
|
CHECK (!monitor.is_scheduled_timebound (job1));
|
|
CHECK (!monitor.is_scheduled_timebound (job2));
|
|
CHECK (!monitor.is_scheduled_background (job1));
|
|
CHECK (!monitor.is_scheduled_background (job2));
|
|
CHECK (!monitor.is_scheduled_freewheeling (job1));
|
|
CHECK (!monitor.is_scheduled_freewheeling (job2));
|
|
|
|
tx.commit();
|
|
|
|
CHECK (!monitor.is_scheduled_timebound (job1));
|
|
CHECK (!monitor.is_scheduled_timebound (job2));
|
|
|
|
CHECK ( monitor.is_scheduled_background (job1));
|
|
CHECK ( monitor.is_scheduled_freewheeling (job2));
|
|
}
|
|
|
|
|
|
/** @test demonstrate how a tree of dependent render jobs
|
|
* can be handed over to the scheduler within a single "transaction"
|
|
*
|
|
* @remarks in the real usage situation, the definition of jobs will be
|
|
* driven by the exploration of a tree-like structure (the JobTicket).
|
|
* For the purpose of this interface demonstration test this recursive
|
|
* invocation structure is just emulated by a simple tail recursion.
|
|
* @see HierarchyOrientationIndicator_test#demonstrate_tree_rebuilding
|
|
*/
|
|
void
|
|
demonstrate_nested_job_specification (SchedulerFrontend& scheduler)
|
|
{
|
|
SchedulerDiagnostics monitor(scheduler);
|
|
|
|
JobTransaction startTx = scheduler.startJobTransaction();
|
|
|
|
uint dummyLevel = 5;
|
|
specifyJobs (startTx, dummyLevel);
|
|
|
|
startTx.commit();
|
|
|
|
for (uint i=0; i <=5; ++i)
|
|
{
|
|
Time nominalTime(dummyFrameStart (i));
|
|
Time deadline(TEST_START_TIME + nominalTime);
|
|
|
|
CHECK (monitor.has_job_scheduled_at (deadline));
|
|
CHECK (nominalTime == monitor.job_at(deadline).parameter.nominalTime);
|
|
}
|
|
}
|
|
|
|
/** recursive helper function to add several levels of prerequisites
|
|
* It is crucial for this function to be recursive: this allows us to represent
|
|
* a complete tree navigation as a sequence of job definitions to be "pulled"
|
|
* out from some opaque source
|
|
*/
|
|
static void
|
|
specifyJobs (JobTransaction& currentTx, uint dummyLevel)
|
|
{
|
|
uint frameNr = dummyLevel;
|
|
Time nominalTime(dummyFrameStart(frameNr));
|
|
Time deadline(TEST_START_TIME + nominalTime);
|
|
|
|
Job job = DummyJob::build(nominalTime, frameNr);
|
|
|
|
currentTx.addJob (deadline, job);
|
|
|
|
if (0 < dummyLevel)
|
|
{
|
|
JobTransaction dependentTx = currentTx.startPrerequisiteTx();
|
|
specifyJobs (dependentTx, dummyLevel-1);
|
|
currentTx.attach (dependentTx);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
/** Register this test class... */
|
|
LAUNCHER(SchedulerInterface_test, "unit engine");
|
|
|
|
}}} // namespace backend::engine::test
|