/* BufferProviderProtocol(Test) - demonstration of buffer provider usage cycle 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 buffer-provider-protocol-test.cpp ** unit test \ref BufferProviderProtocol_test */ #include "lib/error.hpp" #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" #include "lib/test/tracking-dummy.hpp" #include "lib/util-foreach.hpp" #include "steam/engine/testframe.hpp" #include "steam/engine/test-rand-ontology.hpp" #include "steam/engine/diagnostic-buffer-provider.hpp" using util::isSameObject; using util::for_each; namespace steam { namespace engine{ namespace test { using lib::test::Dummy; using steam::engine::BuffHandle; using LERR_(LIFECYCLE); using LERR_(LOGIC); namespace { // Test fixture const uint TEST_ELMS = 20; HashVal do_some_computation (TestFrame const& src, TestFrame& work, int64_t* data) { REQUIRE (data); ont::Param param = src.getChecksum(); ont::manipulateFrame (&work, &src, param); for (uint i=0; i(); 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() ); auto diagnostic = watch(provider); CHECK (diagnostic.buffer_was_used (0)); CHECK (diagnostic.buffer_was_closed (0)); CHECK (testData(0) == diagnostic.accessMemory (0)); } /** @test demonstrate the full sequence of invocations during rendering */ void verifyRenderingUsage() { // Test fixture: allows to track/verify allocations after the fact DiagnosticBufferProvider provider; using DataBuff = std::array; constexpr auto BUFFSIZ = sizeof(DataBuff); BuffDescr desc1 = provider.getDescriptor(); BuffDescr desc2 = provider.getDescriptor(); // note: implies also sizeof(TestFrame) BuffDescr desc3 = provider.getDescriptorFor(BUFFSIZ); // Can also request fixed sized raw storage. CHECK (desc1.isValid()); CHECK (desc2.isValid()); CHECK (desc3.isValid()); uint num1 = desc1.announce(TEST_ELMS); uint num2 = desc1.announce(TEST_ELMS + 1); uint num3 = desc2.announce(TEST_ELMS * 2); CHECK (num1 == TEST_ELMS); CHECK (num2 == TEST_ELMS + 1); CHECK (num3 == TEST_ELMS * 2); // emulate a progressive processing BuffHandle workBuff = desc2.lockBuffer(); workBuff.accessAs() = testData(0); for (uint i=0; i(); size_t& mark = markBuff.accessAs(); TestFrame& work = workBuff.accessAs(); DataBuff& data = dataBuff.accessAs(); mark = do_some_computation (src,work, &data[0]); srcBuff.emit(); dataBuff.emit(); markBuff.emit(); srcBuff.release(); dataBuff.release(); markBuff.release(); // note : workBuff passed to next iteration } CHECK (workBuff.isValid()); auto endSum = workBuff.accessAs().getChecksum(); workBuff.release(); // note: not every buffer need be emitted. CHECK (!workBuff); auto diagnostic = watch(provider); CHECK (diagnostic.buffer_was_used (0)); CHECK (diagnostic.buffer_was_closed (0)); // CHECK (diagnostic.all_buffers_released()); ///////////////OOO do we need this API? } #if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation void verifyObjectAttachment() { DiagnosticBufferProvider provider; BuffDescr type_A = provider.getDescriptorFor(sizeof(TestFrame)); BuffDescr type_B = provider.getDescriptorFor(sizeof(int)); BuffDescr 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() { DiagnosticBufferProvider provider; BuffDescr 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() ); } #endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code }; /** Register this test class... */ LAUNCHER (BufferProviderProtocol_test, "unit engine"); }}} // namespace steam::engine::test