this bit of Sed magic relies on the fact that we happen to write
the almost correct class name of a test into the header comment.
HOWTO:
for F in $(find tests -type f \( -name '*.cpp' \) -exec egrep -q '§§TODO§§' {} \; -print);
do sed -r -i -e'
2 {h;x;s/\s+(.+)\(Test\).*$/\\ref \1_test/;x};
/§§TODO§§/ {s/§§TODO§§//;G;s/\n//}'
$F;
done
198 lines
6.4 KiB
C++
198 lines
6.4 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 \ref SchedulerInterface_test
|
|
*/
|
|
|
|
|
|
#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
|