From a92117be4323e26efe3f13b5c624e5010a7cd26a Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 29 Jul 2009 17:26:37 +1000 Subject: Allow testlib loggers to dynamically allocate storage for strings. This enables very long failure messages (e.g. including an entire build log in a failure message). This change modifies only the plain test logger to use this feature. Task: 253861 Reviewed-by: Michael Goddard --- src/testlib/qabstracttestlogger_p.h | 36 +++++++++++ src/testlib/qplaintestlogger.cpp | 8 ++- src/testlib/qtest_global.h | 1 + src/testlib/qtestcase.cpp | 52 ++++++++++++++-- tests/auto/selftests/expected_longstring.txt | 16 +++++ tests/auto/selftests/longstring/longstring.pro | 10 +++ tests/auto/selftests/longstring/tst_longstring.cpp | 72 ++++++++++++++++++++++ tests/auto/selftests/selftests.pro | 2 +- tests/auto/selftests/selftests.qrc | 1 + tests/auto/selftests/tst_selftests.cpp | 1 + 10 files changed, 189 insertions(+), 10 deletions(-) create mode 100644 tests/auto/selftests/expected_longstring.txt create mode 100644 tests/auto/selftests/longstring/longstring.pro create mode 100644 tests/auto/selftests/longstring/tst_longstring.cpp diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h index a0e8a1e..588184e 100644 --- a/src/testlib/qabstracttestlogger_p.h +++ b/src/testlib/qabstracttestlogger_p.h @@ -99,6 +99,42 @@ public: static bool isTtyOutput(); }; +struct QTestCharBuffer +{ + inline QTestCharBuffer() + : buf(0) + {} + + inline ~QTestCharBuffer() + { + delete[] buf; + buf = 0; + } + + inline operator void*() + { + return buf; + } + + inline operator char*() + { + return buf; + } + + inline operator char**() + { + return &buf; + } + + inline const char* constData() const + { + return buf; + } + +private: + char* buf; +}; + QT_END_NAMESPACE #endif diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp index 071b55e..7bebaa1 100644 --- a/src/testlib/qplaintestlogger.cpp +++ b/src/testlib/qplaintestlogger.cpp @@ -168,7 +168,7 @@ namespace QTest { QTEST_ASSERT(type); QTEST_ASSERT(msg); - char buf[1024]; + QTestCharBuffer buf; const char *fn = QTestResult::currentTestFunction() ? QTestResult::currentTestFunction() : "UnknownTestFunc"; @@ -178,7 +178,7 @@ namespace QTest { : ""; const char *filler = (tag[0] && gtag[0]) ? ":" : ""; if (file) { - QTest::qt_snprintf(buf, sizeof(buf), "%s: %s::%s(%s%s%s)%s%s\n" + QTest::qt_asprintf(buf, "%s: %s::%s(%s%s%s)%s%s\n" #ifdef Q_OS_WIN "%s(%d) : failure location\n" #else @@ -187,10 +187,12 @@ namespace QTest { , type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag, msg[0] ? " " : "", msg, file, line); } else { - QTest::qt_snprintf(buf, sizeof(buf), "%s: %s::%s(%s%s%s)%s%s\n", + QTest::qt_asprintf(buf, "%s: %s::%s(%s%s%s)%s%s\n", type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag, msg[0] ? " " : "", msg); } + // In colored mode, printf above stripped our nonprintable control characters. + // Put them back. memcpy(buf, type, strlen(type)); outputMessage(buf); } diff --git a/src/testlib/qtest_global.h b/src/testlib/qtest_global.h index b5b0fc0..c40f0ad 100644 --- a/src/testlib/qtest_global.h +++ b/src/testlib/qtest_global.h @@ -82,6 +82,7 @@ namespace QTest enum TestFailMode { Abort = 1, Continue = 2 }; int Q_TESTLIB_EXPORT qt_snprintf(char *str, int size, const char *format, ...); + int qt_asprintf(char **str, const char *format, ...); } QT_END_NAMESPACE diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index cb05400..e44be9c 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -808,6 +808,50 @@ namespace QTest static int eventDelay = -1; static int keyVerbose = -1; +void filter_unprintable(char *str) +{ + char *idx = str; + while (*idx) { + if (((*idx < 0x20 && *idx != '\n' && *idx != '\t') || *idx > 0x7e)) + *idx = '?'; + ++idx; + } +} + +int qt_asprintf(char **str, const char *format, ...) +{ + static const int MAXSIZE = 1024*1024*2; + + int size = 32; + delete[] *str; + *str = new char[size]; + + va_list ap; + int res = 0; + + for (;;) { + va_start(ap, format); + res = qvsnprintf(*str, size, format, ap); + va_end(ap); + (*str)[size - 1] = '\0'; + if (res < size) { + // We succeeded or fatally failed + break; + } + // buffer wasn't big enough, try again + size *= 2; + if (size > MAXSIZE) { + break; + } + delete[] *str; + *str = new char[size]; + } + + filter_unprintable(*str); + + return res; +} + /*! \internal */ int qt_snprintf(char *str, int size, const char *format, ...) @@ -820,12 +864,8 @@ int qt_snprintf(char *str, int size, const char *format, ...) va_end(ap); str[size - 1] = '\0'; - char *idx = str; - while (*idx) { - if (((*idx < 0x20 && *idx != '\n' && *idx != '\t') || *idx > 0x7e)) - *idx = '?'; - ++idx; - } + filter_unprintable(str); + return res; } diff --git a/tests/auto/selftests/expected_longstring.txt b/tests/auto/selftests/expected_longstring.txt new file mode 100644 index 0000000..4abdb23 --- /dev/null +++ b/tests/auto/selftests/expected_longstring.txt @@ -0,0 +1,16 @@ +********* Start testing of tst_LongString ********* +Config: Using QTest library 4.6.0, Qt 4.6.0 +PASS : tst_LongString::initTestCase() +FAIL! : tst_LongString::failWithLongString() Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. + +Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. + +Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. + +Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. + +Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + Loc: [/home/rmcgover/depot/qt/master/tests/auto/selftests/longstring/tst_longstring.cpp(67)] +PASS : tst_LongString::cleanupTestCase() +Totals: 2 passed, 1 failed, 0 skipped +********* Finished testing of tst_LongString ********* diff --git a/tests/auto/selftests/longstring/longstring.pro b/tests/auto/selftests/longstring/longstring.pro new file mode 100644 index 0000000..b917481 --- /dev/null +++ b/tests/auto/selftests/longstring/longstring.pro @@ -0,0 +1,10 @@ +load(qttest_p4) +SOURCES += tst_longstring.cpp +QT = core + +mac:CONFIG -= app_bundle +CONFIG -= debug_and_release_target + + +TARGET = longstring + diff --git a/tests/auto/selftests/longstring/tst_longstring.cpp b/tests/auto/selftests/longstring/tst_longstring.cpp new file mode 100644 index 0000000..a708fa7 --- /dev/null +++ b/tests/auto/selftests/longstring/tst_longstring.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include + +char const lipsum[] = +"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.\n\n" +"Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.\n\n" +"Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.\n\n" +"Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis.\n\n" +"Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas." +; + +/*! + \internal + */ +class tst_LongString: public QObject +{ + Q_OBJECT + +private slots: + void failWithLongString() const; +}; + +void tst_LongString::failWithLongString() const +{ + QFAIL(lipsum); +} + +QTEST_MAIN(tst_LongString) + +#include "tst_longstring.moc" diff --git a/tests/auto/selftests/selftests.pro b/tests/auto/selftests/selftests.pro index 45de658..d854b5e 100644 --- a/tests/auto/selftests/selftests.pro +++ b/tests/auto/selftests/selftests.pro @@ -5,7 +5,7 @@ SUBDIRS = subtest test warnings maxwarnings cmptest globaldata skipglobal skip \ skipinit skipinitdata datetime singleskip assert waitwithoutgui differentexec \ exceptionthrow qexecstringlist datatable commandlinedata\ benchlibwalltime benchlibcallgrind benchlibeventcounter benchlibtickcounter \ - benchliboptions xunit badxml + benchliboptions xunit badxml longstring INSTALLS = diff --git a/tests/auto/selftests/selftests.qrc b/tests/auto/selftests/selftests.qrc index 3d78bf5..4b75405 100644 --- a/tests/auto/selftests/selftests.qrc +++ b/tests/auto/selftests/selftests.qrc @@ -36,5 +36,6 @@ expected_benchliboptions.txt expected_benchlibtickcounter.txt expected_xunit.txt + expected_longstring.txt diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index 8eb7fe1..69b84e2 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -191,6 +191,7 @@ void tst_Selftests::runSubTest_data() #endif QTest::newRow("xunit") << "xunit" << QStringList("-xunitxml"); + QTest::newRow("longstring") << "longstring" << QStringList(); } -- cgit v0.12