summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io/qfile
diff options
context:
space:
mode:
authorKurt Korbatits <kurt.korbatits@nokia.com>2012-01-13 14:01:57 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-16 01:55:31 +0100
commitd9a50fc1dc8470adc3b028587ccf6fde9bcb75ab (patch)
tree5d2f3cc1d1321bb3d65950d4308e8b38a65a516c /tests/auto/corelib/io/qfile
parent7940521fd9d985b9565193a5bb8d13fc92ac1042 (diff)
Moved largefile unittest to same level as qfile.
- Moved largefile from out of qfile unittest directory to be on same level as qfile. Change-Id: I479b0b33594812759f8a6a7be61f8340f64234e9 Reviewed-by: Kurt Korbatits <kurt.korbatits@nokia.com> Reviewed-by: Jason McDonald <jason.mcdonald@nokia.com> Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com>
Diffstat (limited to 'tests/auto/corelib/io/qfile')
-rw-r--r--tests/auto/corelib/io/qfile/largefile/largefile.pro6
-rw-r--r--tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp536
-rw-r--r--tests/auto/corelib/io/qfile/qfile.pro2
3 files changed, 0 insertions, 544 deletions
diff --git a/tests/auto/corelib/io/qfile/largefile/largefile.pro b/tests/auto/corelib/io/qfile/largefile/largefile.pro
deleted file mode 100644
index 4e629122ec..0000000000
--- a/tests/auto/corelib/io/qfile/largefile/largefile.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase parallel_test
-TARGET = tst_largefile
-QT = core testlib
-SOURCES = tst_largefile.cpp
-
-wince*: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp
diff --git a/tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp b/tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp
deleted file mode 100644
index ba2eced60a..0000000000
--- a/tests/auto/corelib/io/qfile/largefile/tst_largefile.cpp
+++ /dev/null
@@ -1,536 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QTest>
-
-#include <QtAlgorithms>
-#include <QFile>
-#include <QFileInfo>
-#include <qplatformdefs.h>
-
-#include <QDebug>
-
-#include <cstdlib>
-#include <cstdio>
-
-#ifdef Q_OS_WIN
-
-#include <windows.h>
-
-#ifndef Q_OS_WINCE
-#include <io.h>
-#endif
-
-#ifndef FSCTL_SET_SPARSE
-// MinGW doesn't define this.
-#define FSCTL_SET_SPARSE (0x900C4)
-#endif
-
-#endif // Q_OS_WIN
-
-class tst_LargeFile
- : public QObject
-{
- Q_OBJECT
-
-public:
- tst_LargeFile()
- : blockSize(1 << 12)
- , maxSizeBits()
- , fd_(-1)
- , stream_(0)
- {
- #if defined(QT_LARGEFILE_SUPPORT) && !defined(Q_OS_MAC)
- maxSizeBits = 36; // 64 GiB
- #elif defined(Q_OS_MAC)
- // HFS+ does not support sparse files, so we limit file size for the test
- // on Mac OS.
- maxSizeBits = 32; // 4 GiB
- #else
- maxSizeBits = 24; // 16 MiB
- #endif
- }
-
-private:
- void sparseFileData();
- QByteArray const &getDataBlock(int index, qint64 position);
-
-private slots:
- // The LargeFile test case was designed to be run in order as a single unit
-
- void initTestCase();
- void cleanupTestCase();
-
- void init();
- void cleanup();
-
- // Create and fill large file
- void createSparseFile();
- void fillFileSparsely();
- void closeSparseFile();
-
- // Verify file was created
- void fileCreated();
-
- // Positioning in large files
- void filePositioning();
- void fdPositioning();
- void streamPositioning();
-
- // Read data from file
- void openFileForReading();
- void readFile();
-
- // Map/unmap large file
- void mapFile();
- void mapOffsetOverflow();
-
- void closeFile() { largeFile.close(); }
-
- // Test data
- void fillFileSparsely_data() { sparseFileData(); }
- void filePositioning_data() { sparseFileData(); }
- void fdPositioning_data() { sparseFileData(); }
- void streamPositioning_data() { sparseFileData(); }
- void readFile_data() { sparseFileData(); }
- void mapFile_data() { sparseFileData(); }
-
-private:
- const int blockSize;
- int maxSizeBits;
-
- QFile largeFile;
-
- QVector<QByteArray> generatedBlocks;
-
- int fd_;
- FILE *stream_;
-};
-
-/*
- Convenience function to hide reinterpret_cast when copying a POD directly
- into a QByteArray.
- */
-template <class T>
-static inline void appendRaw(QByteArray &array, T data)
-{
- array.append(reinterpret_cast<char *>(&data), sizeof(T));
-}
-
-/*
- Pad array with filler up to size. On return, array.size() returns size.
- */
-static inline void topUpWith(QByteArray &array, QByteArray filler, int size)
-{
- for (int i = (size - array.size()) / filler.size(); i > 0; --i)
- array.append(filler);
-
- if (array.size() < size) {
- array.append(filler.left(size - array.size()));
- }
-}
-
-/*
- Generate a unique data block containing identifiable data. Unaligned,
- overlapping and partial blocks should not compare equal.
- */
-static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 userBits = -1)
-{
- QByteArray block;
- block.reserve(blockSize);
-
- // Use of counter and randomBits means content of block will be dependent
- // on the generation order. For (file-)systems that do not support sparse
- // files, these can be removed so the test file can be reused and doesn't
- // have to be generated for every run.
-
- static qint64 counter = 0;
-
- qint64 randomBits = ((qint64)qrand() << 32)
- | ((qint64)qrand() & 0x00000000ffffffff);
-
- appendRaw(block, randomBits);
- appendRaw(block, userBits);
- appendRaw(block, counter);
- appendRaw(block, (qint32)0xdeadbeef);
- appendRaw(block, blockSize);
-
- QByteArray userContent = text.toUtf8();
- appendRaw(block, userContent.size());
- block.append(userContent);
- appendRaw(block, (qint64)0);
-
- // size, so far
- appendRaw(block, block.size());
-
- QByteArray filler("0123456789");
- block.append(filler.right(10 - block.size() % 10));
- topUpWith(block, filler, blockSize - 3 * sizeof(qint64));
-
- appendRaw(block, counter);
- appendRaw(block, userBits);
- appendRaw(block, randomBits);
-
- ++counter;
- return block;
-}
-
-/*
- Generates data blocks the first time they are requested. Keeps copies for reuse.
- */
-QByteArray const &tst_LargeFile::getDataBlock(int index, qint64 position)
-{
- if (index >= generatedBlocks.size())
- generatedBlocks.resize(index + 1);
-
- if (generatedBlocks[index].isNull()) {
- QString text = QString("Current %1-byte block (index = %2) "
- "starts %3 bytes into the file '%4'.")
- .arg(blockSize)
- .arg(index)
- .arg(position)
- .arg("qt_largefile.tmp");
-
- generatedBlocks[index] = generateDataBlock(blockSize, text, (qint64)1 << index);
- }
-
- return generatedBlocks[index];
-}
-
-void tst_LargeFile::initTestCase()
-{
- QFile file("qt_largefile.tmp");
- QVERIFY( !file.exists() || file.remove() );
-}
-
-void tst_LargeFile::cleanupTestCase()
-{
- if (largeFile.isOpen())
- largeFile.close();
-
- QFile file("qt_largefile.tmp");
- QVERIFY( !file.exists() || file.remove() );
-}
-
-void tst_LargeFile::init()
-{
- fd_ = -1;
- stream_ = 0;
-}
-
-void tst_LargeFile::cleanup()
-{
- if (-1 != fd_)
- QT_CLOSE(fd_);
- if (stream_)
- ::fclose(stream_);
-}
-
-void tst_LargeFile::sparseFileData()
-{
- QTest::addColumn<int>("index");
- QTest::addColumn<qint64>("position");
- QTest::addColumn<QByteArray>("block");
-
- QTest::newRow(QString("block[%1] @%2)")
- .arg(0).arg(0)
- .toLocal8Bit().constData())
- << 0 << (qint64)0 << getDataBlock(0, 0);
-
- // While on Linux sparse files scale well, on Windows, testing at every
- // power of 2 leads to very large files. i += 4 gives us a good coverage
- // without taxing too much on resources.
- for (int index = 12; index <= maxSizeBits; index += 4) {
- qint64 position = (qint64)1 << index;
- QByteArray block = getDataBlock(index, position);
-
- QTest::newRow(
- QString("block[%1] @%2)")
- .arg(index).arg(position)
- .toLocal8Bit().constData())
- << index << position << block;
- }
-}
-
-void tst_LargeFile::createSparseFile()
-{
-#if defined(Q_OS_WIN32)
- // On Windows platforms, we must explicitly set the file to be sparse,
- // so disk space is not allocated for the full file when writing to it.
- HANDLE handle = ::CreateFileA("qt_largefile.tmp",
- GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
- QVERIFY( INVALID_HANDLE_VALUE != handle );
-
- DWORD bytes;
- if (!::DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0,
- &bytes, NULL)) {
- QWARN("Unable to set test file as sparse. "
- "Limiting test file to 16MiB.");
- maxSizeBits = 24;
- }
-
- int fd = ::_open_osfhandle((intptr_t)handle, 0);
- QVERIFY( -1 != fd );
- QVERIFY( largeFile.open(fd, QIODevice::WriteOnly | QIODevice::Unbuffered) );
-#else // !Q_OS_WIN32
- largeFile.setFileName("qt_largefile.tmp");
- QVERIFY( largeFile.open(QIODevice::WriteOnly | QIODevice::Unbuffered) );
-#endif
-}
-
-void tst_LargeFile::closeSparseFile()
-{
-#if defined(Q_OS_WIN32)
- int fd = largeFile.handle();
-#endif
-
- largeFile.close();
-
-#if defined(Q_OS_WIN32)
- if (-1 != fd)
- ::_close(fd);
-#endif
-}
-
-void tst_LargeFile::fillFileSparsely()
-{
- QFETCH( qint64, position );
- QFETCH( QByteArray, block );
- QCOMPARE( block.size(), blockSize );
-
- static int lastKnownGoodIndex = 0;
- struct ScopeGuard {
- ScopeGuard(tst_LargeFile* test)
- : this_(test)
- , failed(true)
- {
- QFETCH( int, index );
- index_ = index;
- }
-
- ~ScopeGuard()
- {
- if (failed) {
- this_->maxSizeBits = lastKnownGoodIndex;
- QWARN( qPrintable(
- QString("QFile::error %1: '%2'. Maximum size bits reset to %3.")
- .arg(this_->largeFile.error())
- .arg(this_->largeFile.errorString())
- .arg(this_->maxSizeBits)) );
- } else
- lastKnownGoodIndex = qMax<int>(index_, lastKnownGoodIndex);
- }
-
- private:
- tst_LargeFile * const this_;
- int index_;
-
- public:
- bool failed;
- };
-
- ScopeGuard resetMaxSizeBitsOnFailure(this);
-
- QVERIFY( largeFile.seek(position) );
- QCOMPARE( largeFile.pos(), position );
-
- QCOMPARE( largeFile.write(block), (qint64)blockSize );
- QCOMPARE( largeFile.pos(), position + blockSize );
- QVERIFY( largeFile.flush() );
-
- resetMaxSizeBitsOnFailure.failed = false;
-}
-
-void tst_LargeFile::fileCreated()
-{
- QFileInfo info("qt_largefile.tmp");
-
- QVERIFY( info.exists() );
- QVERIFY( info.isFile() );
- QVERIFY( info.size() >= ((qint64)1 << maxSizeBits) + blockSize );
-}
-
-void tst_LargeFile::filePositioning()
-{
- QFETCH( qint64, position );
-
- QFile file("qt_largefile.tmp");
- QVERIFY( file.open(QIODevice::ReadOnly) );
-
- QVERIFY( file.seek(position) );
- QCOMPARE( file.pos(), position );
-}
-
-void tst_LargeFile::fdPositioning()
-{
- QFETCH( qint64, position );
-
- fd_ = QT_OPEN("qt_largefile.tmp",
- QT_OPEN_RDONLY | QT_OPEN_LARGEFILE);
- QVERIFY( -1 != fd_ );
-
- QFile file;
- QVERIFY( file.open(fd_, QIODevice::ReadOnly) );
- QCOMPARE( file.pos(), (qint64)0 );
- QVERIFY( file.seek(position) );
- QCOMPARE( file.pos(), position );
-
- file.close();
-
- QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(0), SEEK_SET), QT_OFF_T(0) );
- QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(position), SEEK_SET), QT_OFF_T(position) );
-
- QVERIFY( file.open(fd_, QIODevice::ReadOnly) );
- QCOMPARE( QT_LSEEK(fd_, QT_OFF_T(0), SEEK_CUR), QT_OFF_T(position) );
- QCOMPARE( file.pos(), position );
- QVERIFY( file.seek(0) );
- QCOMPARE( file.pos(), (qint64)0 );
-
- file.close();
-
- QVERIFY( !QT_CLOSE(fd_) );
- fd_ = -1;
-}
-
-void tst_LargeFile::streamPositioning()
-{
- QFETCH( qint64, position );
-
- stream_ = QT_FOPEN("qt_largefile.tmp", "rb");
- QVERIFY( 0 != stream_ );
-
- QFile file;
- QVERIFY( file.open(stream_, QIODevice::ReadOnly) );
- QCOMPARE( file.pos(), (qint64)0 );
- QVERIFY( file.seek(position) );
- QCOMPARE( file.pos(), position );
-
- file.close();
-
- QVERIFY( !QT_FSEEK(stream_, QT_OFF_T(0), SEEK_SET) );
- QCOMPARE( QT_FTELL(stream_), QT_OFF_T(0) );
- QVERIFY( !QT_FSEEK(stream_, QT_OFF_T(position), SEEK_SET) );
- QCOMPARE( QT_FTELL(stream_), QT_OFF_T(position) );
-
- QVERIFY( file.open(stream_, QIODevice::ReadOnly) );
- QCOMPARE( QT_FTELL(stream_), QT_OFF_T(position) );
- QCOMPARE( file.pos(), position );
- QVERIFY( file.seek(0) );
- QCOMPARE( file.pos(), (qint64)0 );
-
- file.close();
-
- QVERIFY( !::fclose(stream_) );
- stream_ = 0;
-}
-
-void tst_LargeFile::openFileForReading()
-{
- largeFile.setFileName("qt_largefile.tmp");
- QVERIFY( largeFile.open(QIODevice::ReadOnly) );
-}
-
-void tst_LargeFile::readFile()
-{
- QFETCH( qint64, position );
- QFETCH( QByteArray, block );
- QCOMPARE( block.size(), blockSize );
-
- QVERIFY( largeFile.size() >= position + blockSize );
-
- QVERIFY( largeFile.seek(position) );
- QCOMPARE( largeFile.pos(), position );
-
- QCOMPARE( largeFile.read(blockSize), block );
- QCOMPARE( largeFile.pos(), position + blockSize );
-}
-
-void tst_LargeFile::mapFile()
-{
- QFETCH( qint64, position );
- QFETCH( QByteArray, block );
- QCOMPARE( block.size(), blockSize );
-
- // Keep full block mapped to facilitate OS and/or internal reuse by Qt.
- uchar *baseAddress = largeFile.map(position, blockSize);
- QVERIFY( baseAddress );
- QVERIFY( qEqual(block.begin(), block.end(), reinterpret_cast<char*>(baseAddress)) );
-
- for (int offset = 1; offset < blockSize; ++offset) {
- uchar *address = largeFile.map(position + offset, blockSize - offset);
-
- QVERIFY( address );
- if ( !qEqual(block.begin() + offset, block.end(), reinterpret_cast<char*>(address)) ) {
- qDebug() << "Expected:" << block.toHex();
- qDebug() << "Actual :" << QByteArray(reinterpret_cast<char*>(address), blockSize).toHex();
- QVERIFY(false);
- }
-
- QVERIFY( largeFile.unmap( address ) );
- }
-
- QVERIFY( largeFile.unmap( baseAddress ) );
-}
-
-void tst_LargeFile::mapOffsetOverflow()
-{
-#if defined(Q_OS_MAC)
- QSKIP("mmap'ping beyond EOF may succeed; generate bus error on access");
-#endif
-
- // Out-of-range mappings should fail, and not silently clip the offset
- for (int i = 50; i < 63; ++i) {
- uchar *address = 0;
-
- address = largeFile.map(((qint64)1 << i), blockSize);
-#if defined(__x86_64__)
- QEXPECT_FAIL("", "fails on 64-bit Linux (QTBUG-21175)", Abort);
-#endif
- QVERIFY( !address );
-
- address = largeFile.map(((qint64)1 << i) + blockSize, blockSize);
- QVERIFY( !address );
- }
-}
-
-QTEST_APPLESS_MAIN(tst_LargeFile)
-#include "tst_largefile.moc"
-
diff --git a/tests/auto/corelib/io/qfile/qfile.pro b/tests/auto/corelib/io/qfile/qfile.pro
index 8bb142c5b4..e2c714c67f 100644
--- a/tests/auto/corelib/io/qfile/qfile.pro
+++ b/tests/auto/corelib/io/qfile/qfile.pro
@@ -5,6 +5,4 @@ wince* {
SUBDIRS = test stdinprocess
}
-SUBDIRS += largefile
-
CONFIG += parallel_test