From: <sv...@ww...> - 2004-07-17 18:23:30
|
Author: mkrose Date: 2004-07-17 11:23:23 -0700 (Sat, 17 Jul 2004) New Revision: 1161 Added: trunk/CSP/SimData/SimData/Tests/test_CircularBuffer.cpp Modified: trunk/CSP/SimData/CHANGES.current trunk/CSP/SimData/Include/SimData/CircularBuffer.h trunk/CSP/SimData/Makefile trunk/CSP/SimData/SimData/Tests/Makefile trunk/CSP/SimData/SimData/Tests/test_Object.cpp Log: Added circular buffer unittest and tweaked the makefiles slighly to give better test failure reporting. Also fixed a small bug in CircularBuffer, renamed the method for testing the maximum block size that can be allocated, and added a new method to get the total allocated space. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1161 Modified: trunk/CSP/SimData/CHANGES.current =================================================================== --- trunk/CSP/SimData/CHANGES.current 2004-07-17 17:01:58 UTC (rev 1160) +++ trunk/CSP/SimData/CHANGES.current 2004-07-17 18:23:23 UTC (rev 1161) @@ -32,6 +32,12 @@ * Expand the python interface to LogStream to include setting the enabling point and time logging. + * Added circular buffer unittest and tweaked the makefiles slighly to + give better test failure reporting. Also fixed a small bug in + CircularBuffer, renamed the method for testing the maximum block size + that can be allocated, and added a new method to get the total allocated + space. + 2004-07-09: onsight * Changed the formating of HashT values to use fixed-width hex instead of decimal numbers, and cleaned up the data archive Modified: trunk/CSP/SimData/Include/SimData/CircularBuffer.h =================================================================== --- trunk/CSP/SimData/Include/SimData/CircularBuffer.h 2004-07-17 17:01:58 UTC (rev 1160) +++ trunk/CSP/SimData/Include/SimData/CircularBuffer.h 2004-07-17 18:23:23 UTC (rev 1161) @@ -70,7 +70,7 @@ m_buffer = new TYPE[count]; } - uint32 count() const { return m_count; } + uint32 getCount() const { return m_count; } ~RingQueue() { delete[] m_buffer; @@ -207,7 +207,7 @@ m_size = size + RESERVE; m_read = 0; m_write = 0; - m_limit = size; + m_limit = m_size; m_next_read = 0; m_next_write = 0; m_allocated = 0; @@ -246,7 +246,7 @@ inline uint8 *getWriteBuffer(const uint32 size) { // check that there aren't any allocated but uncommitted blocks assert(m_write == m_next_write); - if (size == 0 || getFreeSpace() < size) return 0; + if (size == 0 || getMaximumAllocation() < size) return 0; uint32 offset = m_write; // if no room at the end of the buffer; allocate from the start if (m_size - m_write < size + RESERVE) { @@ -271,7 +271,7 @@ * an upper bound (additional space may be consumed by the writer * thread at any time). */ - inline uint32 getFreeSpace() const { + inline uint32 getMaximumAllocation() const { uint32 read = m_read; if (read > m_write) { if (read - m_write <= RESERVE) return 0; @@ -282,6 +282,24 @@ return 0; } + /** Returns a measure of the number of bytes in the buffer that are + * allocated. Note that getAllocatedBytes() + getMaximumAllocation() + * will generally be less than capacity due to wasted space at the + * end of the buffer. + */ + inline uint32 getAllocatedSpace() const { + uint32 read = m_read; + uint32 write = m_write; + uint32 space; + if (read > write) { + space = (m_size + write) - read; + } else { + space = write - read; + } + if (space > RESERVE) return space - RESERVE; + return 0; + } + /** Returns true if the buffer is empty (no blocks to read). */ inline bool isEmpty() const { Modified: trunk/CSP/SimData/Makefile =================================================================== --- trunk/CSP/SimData/Makefile 2004-07-17 17:01:58 UTC (rev 1160) +++ trunk/CSP/SimData/Makefile 2004-07-17 18:23:23 UTC (rev 1161) @@ -31,8 +31,7 @@ @python setup.py make_install --verbose tests: - @$(MAKE) --no-print-directory -C SimData/Tests all - @SIMDATA_LOGFILE=SimData/Tests/.testlog python SimData/Tests/RunTests.py + @$(MAKE) --no-print-directory -C SimData/Tests all && SIMDATA_LOGFILE=SimData/Tests/.testlog python SimData/Tests/RunTests.py tests-clean: @$(MAKE) --no-print-directory -C SimData/Tests clean Modified: trunk/CSP/SimData/SimData/Tests/Makefile =================================================================== --- trunk/CSP/SimData/SimData/Tests/Makefile 2004-07-17 17:01:58 UTC (rev 1160) +++ trunk/CSP/SimData/SimData/Tests/Makefile 2004-07-17 18:23:23 UTC (rev 1161) @@ -47,16 +47,30 @@ @echo -n "Building $@..." @for foo in a; do \ $(CXX) -o $@ $(CFLAGS) $(@:=.cpp) -L$(TOPDIR)/SimData -lSimData -lpthread 2>.buildlog 1>/dev/null; \ - if [ $$? = "0" ]; then echo "ok"; else echo "failed!"; exit 1; fi; \ + if [ $$? = "0" ]; then echo "ok"; else echo "failed! (see .buildlog for details)"; exit 1; fi; \ done $ run: - @for test in $(TESTS); do \ - echo -n "Running $$test..."; \ - ./$$test 2>$$test.log 1>/dev/null; \ - if [ $$? = "0" ]; then echo "ok"; rm $$test.log; else echo "failed!"; fi; \ - done + @export FAILED_TESTS=0; \ + for test in $(TESTS); do \ + echo -n "Running $$test..."; \ + ./$$test 2>$$test.log 1>/dev/null; \ + if [ $$? = "0" ]; then \ + echo "ok"; \ + rm $$test.log; \ + else \ + echo "failed!"; \ + FAILED_TESTS=`expr $$FAILED_TESTS + 1`; \ + fi; \ + done; \ + if [ $$FAILED_TESTS -gt 0 ]; then \ + echo "********************************************"; \ + echo "$$FAILED_TESTS TEST(S) FAILED!"; \ + echo "********************************************"; \ + exit 1; \ + fi + $ all: $(TESTS) run Added: trunk/CSP/SimData/SimData/Tests/test_CircularBuffer.cpp =================================================================== --- trunk/CSP/SimData/SimData/Tests/test_CircularBuffer.cpp 2004-07-17 17:01:58 UTC (rev 1160) +++ trunk/CSP/SimData/SimData/Tests/test_CircularBuffer.cpp 2004-07-17 18:23:23 UTC (rev 1161) @@ -0,0 +1,116 @@ +/* SimData: Data Infrastructure for Simulations + * Copyright (C) 2004 Mark Rose <mk...@us...> + * + * This file is part of SimData. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +/** + * @file test_CircularBuffer.cpp + * @brief Test the CircularBuffer class. + */ + + +#include <SimData/CircularBuffer.h> +#include <SimData/Trace.h> + +#include <cstdlib> +#include <cassert> +#include <iostream> +#include <deque> + +#define TEST_LOOP_COUNT 1000000 +#define DBG false + +using namespace simdata; + + +void testOneByte() { + std::cerr << "RUNNING ONE BYTE TEST\n"; + CircularBuffer b(433); + assert(b.getAllocatedSpace() == 0); + assert(b.getMaximumAllocation() > 430); + for (int i = 0; i < TEST_LOOP_COUNT; ++i) { + if (DBG) std::cerr << "iteration: " << i << "\n"; + uint8 *x = b.getWriteBuffer(1); + *x = i & 255; + b.commitWriteBuffer(); + uint32 size; + x = b.getReadBuffer(size); + assert(size == 1); + assert(*x == (i & 255)); + b.releaseReadBuffer(); + } + assert(b.getAllocatedSpace() == 0); +} + + +void testRandomUse() { + std::cerr << "RUNNING RANDOM USE TEST\n"; + CircularBuffer b(1024); + std::deque<uint8*> q_ptr; + std::deque<uint32> q_size; + int n = 0; + for (int i = 0; i < TEST_LOOP_COUNT; ++i) { + if (DBG) std::cerr << "iteration: " << i << "\n"; + if (rand() & 1) { + uint32 size; + uint8 *x = b.getReadBuffer(size); + if (x != 0) { + if (DBG) std::cerr << "read " << (void*)x << " " << size << "\n"; + assert(x == q_ptr.front()); + q_ptr.pop_front(); + assert(size == q_size.front()); + q_size.pop_front(); + b.releaseReadBuffer(); + } else { + assert(q_ptr.empty()); + if (DBG) std::cerr << "read --- empty!\n"; + } + } else { + uint32 size = (rand() & 255); + uint8 *x = b.getWriteBuffer(size); + if (x != 0) { + if (DBG) std::cerr << "write " << (void*)x << " " << size << "\n"; + q_ptr.push_back(x); + q_size.push_back(size); + b.commitWriteBuffer(); + } else { + if (DBG) std::cerr << "write --- full! " << q_ptr.size() << "\n"; + } + } + } +} + + +void test() { + testRandomUse(); + testOneByte(); + ::exit(0); +} + + +int main() { + Trace::install(); + test(); + return 0; +}; + + + + + Modified: trunk/CSP/SimData/SimData/Tests/test_Object.cpp =================================================================== --- trunk/CSP/SimData/SimData/Tests/test_Object.cpp 2004-07-17 17:01:58 UTC (rev 1160) +++ trunk/CSP/SimData/SimData/Tests/test_Object.cpp 2004-07-17 18:23:23 UTC (rev 1161) @@ -1,18 +1,18 @@ /* SimData: Data Infrastructure for Simulations * Copyright (C) 2003 Mark Rose <tm...@st...> - * + * * This file is part of SimData. - * + * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -101,7 +101,7 @@ } void test() { - // TODO + // TODO // * set and retrieve values // * split Object class declarations into a header? simdata::InterfaceRegistry ® = simdata::InterfaceRegistry::getInterfaceRegistry(); @@ -126,8 +126,8 @@ ::exit(0); } -int main() { +int main() { test(); - return 0; + return 0; }; |