Stop relying on QHash ordering
authorGiuseppe D'Angelo <dangelog@gmail.com>
Sun, 1 Apr 2012 17:53:55 +0000 (18:53 +0100)
committerQt by Nokia <qt-info@nokia.com>
Tue, 3 Apr 2012 21:56:10 +0000 (23:56 +0200)
tst_rcc and tst_qdom rely on specific QHash orderings inside
rcc and QDom respectively (see QTBUG-25078 and QTBUG-25071).

A workaround is added to make them succeed: QDom checks for
all possible orderings, and rcc initializes the hash seed to 0
if the QT_RCC_TEST environment variable is set.

Change-Id: I5ed6b50602fceba731c797aec8dffc9cc1d6a1ce
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
src/tools/rcc/main.cpp
tests/auto/tools/rcc/tst_rcc.cpp
tests/auto/xml/dom/qdom/tst_qdom.cpp

index 3873e74..ad20b9e 100644 (file)
@@ -47,6 +47,8 @@
 #include <QFile>
 #include <QFileInfo>
 #include <QTextStream>
+#include <QAtomicInt>
+#include <QtGlobal>
 
 QT_BEGIN_NAMESPACE
 
@@ -254,9 +256,16 @@ int runRcc(int argc, char *argv[])
     return library.output(out, errorDevice) ? 0 : 1;
 }
 
+Q_CORE_EXPORT extern QBasicAtomicInt qt_qhash_seed; // from qhash.cpp
+
 QT_END_NAMESPACE
 
 int main(int argc, char *argv[])
 {
+    // rcc uses a QHash to store files in the resource system.
+    // we must force a certain hash order when testing or tst_rcc will fail, see QTBUG-25078
+    if (!qgetenv("QT_RCC_TEST").isEmpty() && !qt_qhash_seed.testAndSetRelaxed(-1, 0))
+        qFatal("Cannot force QHash seed for testing as requested");
+
     return QT_PREPEND_NAMESPACE(runRcc)(argc, argv);
 }
index dbf5ceb..8af85a6 100644 (file)
@@ -52,6 +52,7 @@
 #include <QtCore/QList>
 #include <QtCore/QResource>
 #include <QtCore/QLocale>
+#include <QtCore/QtGlobal>
 
 typedef QMap<QString, QString> QStringMap;
 Q_DECLARE_METATYPE(QStringMap)
@@ -61,6 +62,8 @@ class tst_rcc : public QObject
     Q_OBJECT
 
 private slots:
+    void initTestCase();
+
     void rcc_data();
     void rcc();
     void binary_data();
@@ -69,6 +72,13 @@ private slots:
     void cleanupTestCase();
 };
 
+void tst_rcc::initTestCase()
+{
+    // rcc uses a QHash to store files in the resource system.
+    // we must force a certain hash order when testing or tst_rcc will fail, see QTBUG-25078
+    QVERIFY(qputenv("QT_RCC_TEST", "1"));
+}
+
 QString findExpectedFile(const QString &base)
 {
     QString expectedrccfile = base;
index 1533e6a..1155cd0 100644 (file)
@@ -1792,8 +1792,15 @@ void tst_QDom::doubleNamespaceDeclarations() const
     QXmlInputSource source(&file);
     QVERIFY(doc.setContent(&source, &reader));
 
-    QVERIFY(doc.toString(0) == QString::fromLatin1("<a>\n<b p:c=\"\" xmlns:p=\"NS\" p:d=\"\"/>\n</a>\n") ||
-            doc.toString(0) == QString::fromLatin1("<a>\n<b p:c=\"\" p:d=\"\" xmlns:p=\"NS\"/>\n</a>\n"));
+    // tst_QDom relies on a specific QHash ordering, see QTBUG-25071
+    QString docAsString = doc.toString(0);
+    QVERIFY(docAsString == QString::fromLatin1("<a>\n<b p:c=\"\" xmlns:p=\"NS\" p:d=\"\"/>\n</a>\n") ||
+            docAsString == QString::fromLatin1("<a>\n<b p:c=\"\" p:d=\"\" xmlns:p=\"NS\"/>\n</a>\n") ||
+            docAsString == QString::fromLatin1("<a>\n<b p:d=\"\" p:c=\"\" xmlns:p=\"NS\"/>\n</a>\n") ||
+            docAsString == QString::fromLatin1("<a>\n<b p:d=\"\" xmlns:p=\"NS\" p:c=\"\"/>\n</a>\n") ||
+            docAsString == QString::fromLatin1("<a>\n<b xmlns:p=\"NS\" p:c=\"\" p:d=\"\"/>\n</a>\n") ||
+            docAsString == QString::fromLatin1("<a>\n<b xmlns:p=\"NS\" p:d=\"\" p:c=\"\"/>\n</a>\n")
+            );
 }
 
 void tst_QDom::setContentQXmlReaderOverload() const
@@ -1922,7 +1929,7 @@ void tst_QDom::cloneDTD_QTBUG8398() const
     QVERIFY(domDocument.setContent(dtd));
     QDomDocument domDocument2 = domDocument.cloneNode(true).toDocument();
 
-    // for some reason, our DOM implementation reverts the order of entities
+    // this string is relying on a specific QHash ordering, QTBUG-25071
     QString expected("<?xml version='1.0' encoding='UTF-8'?>\n"
                    "<!DOCTYPE first [\n"
                    "<!ENTITY thirdFile SYSTEM 'third.xml'>\n"
@@ -1932,7 +1939,8 @@ void tst_QDom::cloneDTD_QTBUG8398() const
     QString output;
     QTextStream stream(&output);
     domDocument2.save(stream, 0);
-    QCOMPARE(output, expected);
+    // check against the original string and the expected one, QTBUG-25071
+    QVERIFY(output == dtd || output == expected);
 }
 
 void tst_QDom::DTDNotationDecl()