diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2014-04-11 09:12:45 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-04-19 11:41:53 +0200 |
commit | 1a91de7e61eb0030d2704a37d68af9e16219141f (patch) | |
tree | debf1a211a0cf0b6ee356b73c7eaa873ef9bf121 /tests/auto/core/qboundedcircularbuffer/tst_qboundedcircularbuffer.cpp | |
parent | c7ce596dbd3d465c0d0c83b1e020e5eaae32892d (diff) |
Add QBoundedCircularBuffer and test
Change-Id: Ied0bd701fa653396b657ea5c2f2097eb7a425953
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'tests/auto/core/qboundedcircularbuffer/tst_qboundedcircularbuffer.cpp')
-rw-r--r-- | tests/auto/core/qboundedcircularbuffer/tst_qboundedcircularbuffer.cpp | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/tests/auto/core/qboundedcircularbuffer/tst_qboundedcircularbuffer.cpp b/tests/auto/core/qboundedcircularbuffer/tst_qboundedcircularbuffer.cpp new file mode 100644 index 000000000..2b1e7ccd1 --- /dev/null +++ b/tests/auto/core/qboundedcircularbuffer/tst_qboundedcircularbuffer.cpp @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QObject> +#include <QtTest/QtTest> + +#include <Qt3DCore/qboundedcircularbuffer.h> + +using namespace Qt3D; + +class tst_QBoundedCircularBuffer : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void construction(); + void clear(); + void push(); + void pop(); + void at(); + void producerConsumer(); +}; + +class MyComplexType +{ +public: + MyComplexType(int xx = 0) + : x(xx), + magicCheck(ms_magic) + { + ++ms_activeCount; + } + + MyComplexType(const MyComplexType &other) + : x(other.x), + magicCheck(other.magicCheck) + { + ++ms_activeCount; + } + + ~MyComplexType() + { + // Check that the constructor was actually called + QVERIFY(ms_magic == magicCheck); + --ms_activeCount; + } + + MyComplexType &operator=(const MyComplexType &other) + { + if (this == &other) + return *this; + x = other.x; + magicCheck = other.magicCheck; + return *this; + } + + int x; + int magicCheck; + + static const int ms_magic = 0xfefefefe; + static int ms_activeCount; +}; + +int MyComplexType::ms_activeCount = 0; + +void tst_QBoundedCircularBuffer::construction() +{ + QBoundedCircularBuffer<int> buffer(10); + QVERIFY(buffer.capacity() == 10); + QVERIFY(buffer.freeSize() == 10); + QVERIFY(buffer.size() == 0); + QVERIFY(buffer.isEmpty() == true); + QVERIFY(buffer.isFull() == false); +} + +void tst_QBoundedCircularBuffer::clear() +{ + QBoundedCircularBuffer<int> buffer(10); + buffer.clear(); + QVERIFY(buffer.capacity() == 10); + QVERIFY(buffer.freeSize() == 10); + QVERIFY(buffer.size() == 0); + QVERIFY(buffer.isEmpty() == true); + QVERIFY(buffer.isFull() == false); +} + +void tst_QBoundedCircularBuffer::push() +{ + QBoundedCircularBuffer<MyComplexType> buffer(20); + QVERIFY(buffer.freeSize() == 20); + for (int i = 0; i < 15; i++) { + const MyComplexType value(i); + buffer.push(value); + const MyComplexType testValue = buffer.back(); + QVERIFY(testValue.x == value.x); + } + QVERIFY(buffer.freeSize() == 5); + QVERIFY(buffer.size() == 15); +} + +void tst_QBoundedCircularBuffer::pop() +{ + QBoundedCircularBuffer<MyComplexType> buffer(20); + for (int i = 0; i < 15; i++) { + const MyComplexType value(i); + buffer.push(value); + } + + for (int j = 0; j < 10; j++) { + const MyComplexType value = buffer.pop(); + QVERIFY(value.x == j); + } + QVERIFY(buffer.freeSize() == 15); + QVERIFY(buffer.size() == 5); +} + +void tst_QBoundedCircularBuffer::at() +{ + QBoundedCircularBuffer<MyComplexType> buffer(20); + for (int i = 0; i < 10; i++) { + const MyComplexType value(i); + buffer.append(value); + } + + for (int i = 0; i < 10; i++) + QVERIFY(buffer.at(i).x == i); +} + +class MyProducer : public QThread +{ + Q_OBJECT +public: + MyProducer(QBoundedCircularBuffer<MyComplexType> *buffer) + : QThread(), + m_buffer(buffer) + { + } + + void run() + { + for (int i = 0; i < 10000; i++ ) { + //qDebug() << "Producing" << i; + const MyComplexType value(i); + //if ( m_buffer->isFull() ) + // qDebug() << i << "The buffer is full. Waiting for consumer..."; + m_buffer->push(value); + + // Uncomment and adjust this to slow the producer down + // usleep(130); + } + } + +private: + QBoundedCircularBuffer<MyComplexType>* m_buffer; +}; + +class MyConsumer : public QThread +{ + Q_OBJECT +public: + MyConsumer(QBoundedCircularBuffer<MyComplexType>* buffer) + : QThread(), + m_buffer(buffer) + {} + + void run() + { + for (int i = 0; i < 10000; i++) { + //qDebug() << "Consuming" << i; + //if (m_buffer->isEmpty()) + // qDebug() << i << "The buffer is empty. Waiting for producer..."; + const MyComplexType value = m_buffer->pop(); + QVERIFY(value.x == i); + + // Uncomment and adjust this to slow the consumer down + //usleep(100); + } + } + +private: + QBoundedCircularBuffer<MyComplexType>* m_buffer; +}; + +void tst_QBoundedCircularBuffer::producerConsumer() +{ + QBoundedCircularBuffer<MyComplexType> *buffer = new QBoundedCircularBuffer<MyComplexType>(20); + MyProducer producer(buffer); + MyConsumer consumer(buffer); + + // Produce and consume... + producer.start(); + consumer.start(); + + // Wait until both threads are done + producer.wait(); + consumer.wait(); + + // Check all items have been consumed + QVERIFY(buffer->freeSize() == 20); + QVERIFY(buffer->size() == 0); + + // Cleanup + delete buffer; +} + +QTEST_APPLESS_MAIN(tst_QBoundedCircularBuffer) +#include "tst_qboundedcircularbuffer.moc" |