/* BufferProviderProtocol(Test) - demonstration of buffer provider usage cycle Copyright (C) Lumiera.org 2011, 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. * *****************************************************/ #include "lib/error.hpp" #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" #include "lib/test/testdummy.hpp" #include "lib/util-foreach.hpp" #include "proc/engine/testframe.hpp" #include "proc/engine/diagnostic-buffer-provider.hpp" #include "proc/engine/buffhandle-attach.hpp" #include "proc/engine/bufftable.hpp" using util::isSameObject; using util::for_each; namespace proc { namespace engine{ namespace test { using lib::test::Dummy; using proc::engine::BuffHandle; using error::LUMIERA_ERROR_LOGIC; using error::LUMIERA_ERROR_LIFECYCLE; namespace { // Test fixture const uint TEST_SIZE = 1024*1024; const uint TEST_ELMS = 20; void do_some_calculations (BuffHandle const& buffer) { UNIMPLEMENTED ("some verifiable test/dummy buffer accessing operations"); } } /****************************************************************************** * @test verify and demonstrate the usage cycle of data buffers for the engine * based on the BufferProvider interface. This is kind of a "dry run" * for documentation purposes, because the BufferProvider implementation * used here is just a diagnostics facility, allowing to investigate * the state of individual buffers even after "releasing" them. * * This test should help understanding the sequence of buffer management * operations performed at various stages while passing an calculation job * through the render engine. */ class BufferProviderProtocol_test : public Test { virtual void run (Arg) { verifySimpleUsage(); verifyStandardCase(); verifyObjectAttachment(); verifyObjectAttachmentFailure(); } void verifySimpleUsage() { // Create Test fixture. // In real usage, a suitable memory/frame/buffer provider // will be preconfigured, depending on the usage context BufferProvider& provider = DiagnosticBufferProvider::build(); BuffHandle buff = provider.lockBufferFor(); CHECK (buff.isValid()); CHECK (sizeof(TestFrame) <= buff.size()); buff.accessAs() = testData(0); TestFrame& content = buff.accessAs(); CHECK (testData(0) == content); buff.emit(); buff.release(); CHECK (!buff.isValid()); VERIFY_ERROR (LIFECYCLE, buff.accessAs() ); DiagnosticBufferProvider& checker = DiagnosticBufferProvider::access(provider); CHECK (checker.buffer_was_used (0)); CHECK (checker.buffer_was_closed (0)); CHECK (testData(0) == checker.accessMemory (0)); } void verifyStandardCase() { #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #829 // Create Test fixture. // In real usage, a suitable memory/frame/buffer provider // will be preconfigured, depending on the usage context BufferProvider& provider = DiagnosticBufferProvider::build(); BufferDescriptor desc1 = provider.getDescriptor(); // note: implies also sizeof(TestFrame) BufferDescriptor desc2 = provider.getDescriptorFor(TEST_SIZE); CHECK (desc1.verifyValidity()); CHECK (desc2.verifyValidity()); uint num1 = provider.announce(TEST_ELMS, desc1); uint num2 = provider.announce(TEST_ELMS, desc2); CHECK (num1 == TEST_ELMS); CHECK (0 < num2 && num2 <=TEST_ELMS); const size_t STORAGE_SIZE = BuffTable::Storage<2*TEST_ELMS>::size; char storage[STORAGE_SIZE]; BuffTable& tab = BuffTable::prepare(STORAGE_SIZE, storage) .announce(num1, desc1) .announce(num2, desc2) .build(); tab.lockBuffers(); for_each (tab.buffers(), do_some_calculations); tab.releaseBuffers(); DiagnosticBufferProvider& checker = DiagnosticBufferProvider::access(provider); CHECK (checker.all_buffers_released()); #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #829 } void verifyObjectAttachment() { BufferProvider& provider = DiagnosticBufferProvider::build(); BufferDescriptor type_A = provider.getDescriptorFor(sizeof(TestFrame)); BufferDescriptor type_B = provider.getDescriptorFor(sizeof(int)); BufferDescriptor type_C = provider.getDescriptor(); BuffHandle handle_A = provider.lockBuffer(type_A); BuffHandle handle_B = provider.lockBuffer(type_B); BuffHandle handle_C = provider.lockBuffer(type_C); CHECK (handle_A); CHECK (handle_B); CHECK (handle_C); CHECK (sizeof(TestFrame) == handle_A.size()); CHECK (sizeof( int ) == handle_B.size()); CHECK (sizeof( int ) == handle_C.size()); TestFrame& embeddedFrame = handle_A.create(); CHECK (isSameObject (*handle_A, embeddedFrame)); CHECK (embeddedFrame.isAlive()); CHECK (embeddedFrame.isSane()); VERIFY_ERROR (LOGIC, handle_B.create()); // too small to hold a TestFrame VERIFY_ERROR (LIFECYCLE, handle_C.create()); // has already an attached TypeHandler (creating an int) handle_A.release(); handle_B.release(); handle_C.release(); CHECK (embeddedFrame.isDead()); CHECK (embeddedFrame.isSane()); } void verifyObjectAttachmentFailure() { BufferProvider& provider = DiagnosticBufferProvider::build(); BufferDescriptor type_D = provider.getDescriptorFor(sizeof(Dummy)); Dummy::checksum() = 0; BuffHandle handle_D = provider.lockBuffer(type_D); CHECK (0 == Dummy::checksum()); // nothing created thus far handle_D.create(); CHECK (0 < Dummy::checksum()); handle_D.release(); CHECK (0 == Dummy::checksum()); BuffHandle handle_DD = provider.lockBuffer(type_D); CHECK (0 == Dummy::checksum()); Dummy::activateCtorFailure(); CHECK (handle_DD.isValid()); try { handle_DD.create(); NOTREACHED ("Dummy ctor should fail"); } catch (int val) { CHECK (!handle_DD.isValid()); CHECK (0 < Dummy::checksum()); CHECK (val == Dummy::checksum()); } VERIFY_ERROR (LIFECYCLE, handle_DD.accessAs() ); VERIFY_ERROR (LIFECYCLE, handle_DD.create() ); } }; /** Register this test class... */ LAUNCHER (BufferProviderProtocol_test, "unit player"); }}} // namespace proc::engine::test