/* TestFrame(Test) - verify proper operation of dummy data frames Copyright (C) 2011, Hermann Vosseler   **Lumiera** 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. See the file COPYING for further details. * *****************************************************************/ /** @file testframe-test.cpp ** unit test \ref TestFrame_test */ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" #include "steam/engine/testframe.hpp" #include "lib/util.hpp" #include #include using test::Test; using util::isSameObject; using std::unique_ptr; namespace steam { namespace engine{ namespace test { namespace { // used internally const uint CHAN_COUNT = 30; // independent families of test frames to generate const uint NUM_FRAMES = 1000; // number of test frames in each of these families void corruptMemory(void* base, uint offset, uint count) { char* accessor = reinterpret_cast (base); while (count--) accessor[offset+count] = rani(CHAR_MAX); } } // (End) internal defs /***************************************************************//** * @test verify test helper for engine tests: a dummy data frame. * TestFrame instances can be created right away, without any * external library dependencies. A test frame is automatically * filled with random data; multiple frames are arranged in * sequences and channels, causing the random data to be * reproducible yet different in each frame. * * To ease writing unit tests, TestFrame provides comparison * and assignment and tracks lifecycle automatically. As tests * regarding the engine typically have to deal with buffer * management, an arbitrary memory location can be interpreted * as TestFrame and checked for corruption. */ class TestFrame_test : public Test { virtual void run (Arg) { seedRand(); TestFrame::reseed(); simpleUsage(); verifyDataContent(); verifyFrameLifecycle(); verifyFrameSeries(); useFrameTable(); } void simpleUsage() { CHECK (1024 < sizeof(TestFrame)); TestFrame frame; CHECK (frame.isValid()); ++frame.data()[5]; CHECK (not frame.isValid()); frame.markChecksum(); CHECK (frame.isValid()); CHECK (isSameObject(frame, frame.data())); // payload data stored embedded CHECK (sizeof(TestFrame) > frame.data().size()); // additional metadata placed behind } void verifyDataContent() { TestFrame frameA; TestFrame frameB; TestFrame frameC(5); CHECK (frameA == frameB); CHECK (frameA != frameC); CHECK (frameB != frameC); CHECK (frameA.data() == frameB.data()); CHECK (frameA.data() != frameC.data()); for (uint i=0; iisDead()); CHECK ( frame->isAlive()); CHECK ( frame->isValid()); frame->~TestFrame(); CHECK ( TestFrame::isDead (frame)); CHECK (not TestFrame::isAlive (frame)); CHECK ( frame->isValid()); CHECK ( frame->isSane()); } /** @test build sequences of test frames, * organised into multiple families (channels). * Verify that adjacent frames hold differing data */ void verifyFrameSeries() { unique_ptr thisFrames[CHAN_COUNT]; unique_ptr prevFrames[CHAN_COUNT]; for (uint i=0; iisPristine()); CHECK (prevFrames[i]->isPristine()); CHECK (prevFrames[i]->isAlive()); CHECK (*thisFrames[i] != *prevFrames[i]); // differs from predecessor within the same channel for (uint j=0; j