tst_qfilesystemmodel: Do not use nested calls of auto test functions

Calling rowCount inside another auto test function yields unexpected
results, if rowCount fails. Without a check for QTest::currentTestFailed
the failure will not stop the calling function and other functions like
rowsInserted and rowsRemoved might happily continue even though their
requirements are not met. That caused a crash on winrt under certain
circumstances.

In addition to that TRY_WAIT now does not only wait for the given
amount of time, but also gives feedback about its result. Before
this change TRY_WAIT was basically useless, as it gave no indication
about its success/failure.

Fixes: QTBUG-71121
Change-Id: Ibd3f233a0b913db799814be97c4274d510643c74
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
Oliver Wolff 2018-10-15 09:51:12 +02:00
parent ebfad73b4e
commit e524724f9d

View File

@ -51,10 +51,15 @@
// Will try to wait for the condition while allowing event processing // Will try to wait for the condition while allowing event processing
// for a maximum of 5 seconds. // for a maximum of 5 seconds.
#define TRY_WAIT(expr) \ #define TRY_WAIT(expr, timedOut) \
do { \ do { \
*timedOut = true; \
const int step = 50; \ const int step = 50; \
for (int __i = 0; __i < 5000 && !(expr); __i+=step) { \ for (int __i = 0; __i < 5000; __i += step) { \
if (expr) { \
*timedOut = false; \
break; \
} \
QTest::qWait(step); \ QTest::qWait(step); \
} \ } \
} while(0) } while(0)
@ -123,6 +128,8 @@ private slots:
protected: protected:
bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList()); bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList());
QModelIndex prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2 = nullptr,
QSignalSpy **spy3 = nullptr);
private: private:
QFileSystemModel *model; QFileSystemModel *model;
@ -306,7 +313,11 @@ void tst_QFileSystemModel::iconProvider()
bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs) bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs)
{ {
//qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files; //qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files;
TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount)); bool timedOut = false;
TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount), &timedOut);
if (timedOut)
return false;
for (int i = 0; i < initial_dirs.count(); ++i) { for (int i = 0; i < initial_dirs.count(); ++i) {
QDir dir(test_path); QDir dir(test_path);
if (!dir.exists()) { if (!dir.exists()) {
@ -363,23 +374,45 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi
return true; return true;
} }
void tst_QFileSystemModel::rowCount() QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2,
QSignalSpy **spy3)
{ {
QString tmp = flatDirTestPath; if (model->rowCount(model->index(test_path)) != 0)
QVERIFY(createFiles(tmp, QStringList())); return QModelIndex();
QSignalSpy spy2(model, SIGNAL(rowsInserted(QModelIndex,int,int))); if (spy2)
QSignalSpy spy3(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); *spy2 = new QSignalSpy(model, &QFileSystemModel::rowsInserted);
if (spy3)
*spy3 = new QSignalSpy(model, &QFileSystemModel::rowsAboutToBeInserted);
QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j" << ".a" << ".c" << ".e" << ".g"; QStringList files = { "b", "d", "f", "h", "j", ".a", ".c", ".e", ".g" };
QString l = "b,d,f,h,j,.a,.c,.e,.g"; QString l = "b,d,f,h,j,.a,.c,.e,.g";
QVERIFY(createFiles(tmp, files)); if (!createFiles(test_path, files))
return QModelIndex();
QModelIndex root = model->setRootPath(tmp); QModelIndex root = model->setRootPath(test_path);
QTRY_COMPARE(model->rowCount(root), 5); if (!root.isValid())
QVERIFY(spy2.count() > 0); return QModelIndex();
QVERIFY(spy3.count() > 0);
bool timedOut = false;
TRY_WAIT(model->rowCount(root) == 5, &timedOut);
if (timedOut)
return QModelIndex();
return root;
}
void tst_QFileSystemModel::rowCount()
{
const QString tmp = flatDirTestPath;
QSignalSpy *spy2 = nullptr;
QSignalSpy *spy3 = nullptr;
QModelIndex root = prepareTestModelRoot(flatDirTestPath, &spy2, &spy3);
QVERIFY(root.isValid());
QVERIFY(spy2 && spy2->count() > 0);
QVERIFY(spy3 && spy3->count() > 0);
} }
void tst_QFileSystemModel::rowsInserted_data() void tst_QFileSystemModel::rowsInserted_data()
@ -401,9 +434,9 @@ static inline QString lastEntry(const QModelIndex &root)
void tst_QFileSystemModel::rowsInserted() void tst_QFileSystemModel::rowsInserted()
{ {
QString tmp = flatDirTestPath; const QString tmp = flatDirTestPath;
rowCount(); QModelIndex root = prepareTestModelRoot(tmp);
QModelIndex root = model->index(model->rootPath()); QVERIFY(root.isValid());
QFETCH(int, ascending); QFETCH(int, ascending);
QFETCH(int, count); QFETCH(int, count);
@ -454,9 +487,9 @@ void tst_QFileSystemModel::rowsRemoved_data()
void tst_QFileSystemModel::rowsRemoved() void tst_QFileSystemModel::rowsRemoved()
{ {
QString tmp = flatDirTestPath; const QString tmp = flatDirTestPath;
rowCount(); QModelIndex root = prepareTestModelRoot(tmp);
QModelIndex root = model->index(model->rootPath()); QVERIFY(root.isValid());
QFETCH(int, count); QFETCH(int, count);
QFETCH(int, ascending); QFETCH(int, ascending);
@ -509,9 +542,9 @@ void tst_QFileSystemModel::dataChanged()
{ {
QSKIP("This can't be tested right now since we don't watch files, only directories."); QSKIP("This can't be tested right now since we don't watch files, only directories.");
QString tmp = flatDirTestPath; const QString tmp = flatDirTestPath;
rowCount(); QModelIndex root = prepareTestModelRoot(tmp);
QModelIndex root = model->index(model->rootPath()); QVERIFY(root.isValid());
QFETCH(int, count); QFETCH(int, count);
QFETCH(int, assending); QFETCH(int, assending);