1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
44 #include <QtNetwork/QHostInfo>
50 #include <sys/socket.h>
52 #include <QSharedPointer>
55 #if defined(Q_OS_SYMBIAN)
56 #if defined(Q_CC_NOKIAX86)
57 // In emulator we use WINSOCK connectivity by default. Unfortunately winsock
58 // does not work very well with UDP sockets. This defines skips some test
59 // cases which have known problems.
61 // NOTE: Prefer to use WINPCAP based connectivity in S60 emulator when running
62 // network tests. WINPCAP connectivity uses Symbian OS IP stack,
63 // correspondingly as HW does. When using WINPCAP disable this define
64 //#define SYMBIAN_WINSOCK_CONNECTIVITY
65 #endif // Q_CC_NOKIAX86
67 // FIXME: any reason we do this for symbian only, and not other platforms?
68 class QtNetworkSettingsRecord {
70 QtNetworkSettingsRecord() { }
72 QtNetworkSettingsRecord(const QString& recName, const QString& recVal)
73 : strRecordName(recName), strRecordValue(recVal) { }
75 QtNetworkSettingsRecord(const QtNetworkSettingsRecord & other)
76 : strRecordName(other.strRecordName), strRecordValue(other.strRecordValue) { }
78 ~QtNetworkSettingsRecord() { }
80 const QString& recordName() const { return strRecordName; }
81 const QString& recordValue() const { return strRecordValue; }
84 QString strRecordName;
85 QString strRecordValue;
88 #endif // Q_OS_SYMBIAN
90 class QtNetworkSettings
94 static QString serverLocalName()
99 if(QtNetworkSettings::entries.contains("server.localname")) {
100 QtNetworkSettingsRecord* entry = entries["server.localname"];
101 return entry->recordValue();
104 return QString("qt-test-server");
106 static QString serverDomainName()
111 if(QtNetworkSettings::entries.contains("server.domainname")) {
112 QtNetworkSettingsRecord* entry = entries["server.domainname"];
113 return entry->recordValue();
116 return QString("qt-test-net");
118 static QString serverName()
123 return serverLocalName() + "." + serverDomainName();
125 static QString winServerName()
129 static QString wildcardServerName()
131 return "qt-test-server.wildcard.dev." + serverDomainName();
134 #ifdef QT_NETWORK_LIB
135 static QHostAddress serverIP()
140 if(QtNetworkSettings::entries.contains("server.ip")) {
141 QtNetworkSettingsRecord* entry = entries["server.ip"];
142 if(serverIp.isNull()) {
143 serverIp = entry->recordValue().toAscii();
145 return QHostAddress(serverIp.data());
147 #endif // Q_OS_SYMBIAN
148 return QHostInfo::fromName(serverName()).addresses().first();
152 static bool compareReplyIMAP(QByteArray const& actual)
154 QList<QByteArray> expected;
159 if(QtNetworkSettings::entries.contains("imap.expectedreply")) {
160 QtNetworkSettingsRecord* entry = entries["imap.expectedreply"];
161 if(imapExpectedReply.isNull()) {
162 imapExpectedReply = entry->recordValue().toAscii();
163 imapExpectedReply.append('\r').append('\n');
165 expected << imapExpectedReply.data();
169 // Mandriva; old test server
170 expected << QByteArray( "* OK [CAPABILITY IMAP4 IMAP4rev1 LITERAL+ ID STARTTLS LOGINDISABLED] " )
171 .append(QtNetworkSettings::serverName().toAscii())
172 .append(" Cyrus IMAP4 v2.3.11-Mandriva-RPM-2.3.11-6mdv2008.1 server ready\r\n");
174 // Ubuntu 10.04; new test server
175 expected << QByteArray( "* OK " )
176 .append(QtNetworkSettings::serverLocalName().toAscii())
177 .append(" Cyrus IMAP4 v2.2.13-Debian-2.2.13-19 server ready\r\n");
179 // Feel free to add more as needed
181 Q_FOREACH (QByteArray const& ba, expected) {
190 static bool compareReplyIMAPSSL(QByteArray const& actual)
192 QList<QByteArray> expected;
197 if(QtNetworkSettings::entries.contains("imap.expectedreplyssl")) {
198 QtNetworkSettingsRecord* entry = entries["imap.expectedreplyssl"];
199 if(imapExpectedReplySsl.isNull()) {
200 imapExpectedReplySsl = entry->recordValue().toAscii();
201 imapExpectedReplySsl.append('\r').append('\n');
203 expected << imapExpectedReplySsl.data();
206 // Mandriva; old test server
207 expected << QByteArray( "* OK [CAPABILITY IMAP4 IMAP4rev1 LITERAL+ ID AUTH=PLAIN SASL-IR] " )
208 .append(QtNetworkSettings::serverName().toAscii())
209 .append(" Cyrus IMAP4 v2.3.11-Mandriva-RPM-2.3.11-6mdv2008.1 server ready\r\n");
211 // Ubuntu 10.04; new test server
212 expected << QByteArray( "* OK " )
213 .append(QtNetworkSettings::serverLocalName().toAscii())
214 .append(" Cyrus IMAP4 v2.2.13-Debian-2.2.13-19 server ready\r\n");
216 // Feel free to add more as needed
218 Q_FOREACH (QByteArray const& ba, expected) {
227 static bool compareReplyFtp(QByteArray const& actual)
229 QList<QByteArray> expected;
231 // A few different vsFTPd versions.
232 // Feel free to add more as needed
233 expected << QByteArray( "220 (vsFTPd 2.0.5)\r\n221 Goodbye.\r\n" );
234 expected << QByteArray( "220 (vsFTPd 2.2.2)\r\n221 Goodbye.\r\n" );
236 Q_FOREACH (QByteArray const& ba, expected) {
246 static void setDefaultIap()
251 if(entries.contains("iap.default")) {
252 QtNetworkSettingsRecord* entry = entries["iap.default"];
253 QByteArray tmp(entry->recordValue().toAscii());
254 strcpy( ifReq.ifr_name, tmp.data());
256 else // some default value
257 strcpy( ifReq.ifr_name, "Lab");
259 int err = setdefaultif( &ifReq );
261 printf("Setting default IAP - '%s' failed: %d\n", ifReq.ifr_name, err);
263 printf("'%s' used as an default IAP\n", ifReq.ifr_name);
271 static QHash<QString, QtNetworkSettingsRecord* > entries;
272 static bool bDefaultIapLoaded;
273 static bool bTestSettingsLoaded;
274 static QString iapFileFullPath;
275 static QByteArray serverIp;
276 static QByteArray imapExpectedReply;
277 static QByteArray imapExpectedReplySsl;
279 static bool loadDefaultIap() {
280 if(bDefaultIapLoaded)
283 QFile iapCfgFile(iapFileFullPath);
285 bool bFoundDefaultIapTag = false;
287 if (iapCfgFile.open(QFile::ReadOnly)) {
288 QTextStream input(&iapCfgFile);
291 line = input.readLine().trimmed();
292 if(line.startsWith(QString("#")))
293 continue; // comment found
295 if(line.contains(QString("[DEFAULT]"))) {
296 bFoundDefaultIapTag = true;
297 } else if(line.contains(QString("[")) && bFoundDefaultIapTag) {
301 if(bFoundDefaultIapTag && line.contains("name")) {
302 int position = line.indexOf(QString("="));
303 position += QString("=").length();
306 QtNetworkSettingsRecord *entry =
307 new QtNetworkSettingsRecord( QString("iap.default"), line.mid(position).trimmed() );
308 entries.insert(entry->recordName(), entry);
311 } while (!line.isNull());
314 return bDefaultIapLoaded = bFoundDefaultIapTag;
317 static bool loadTestSettings() {
318 if(bTestSettingsLoaded)
321 QFile cfgFile(iapFileFullPath);
322 bool bFoundTestTag = false;
324 if (cfgFile.open(QFile::ReadOnly)) {
325 QTextStream input(&cfgFile);
328 line = input.readLine().trimmed();
330 if(line.startsWith(QString("#")) || line.length() == 0)
331 continue; // comment or empty line found
333 if(line.contains(QString("[TEST]"))) {
334 bFoundTestTag = true;
335 } else if(line.startsWith(QString("[")) && bFoundTestTag) {
336 bFoundTestTag = false;
337 break; // finished with test tag
340 if(bFoundTestTag) { // non-empty line
341 int position = line.indexOf(QString("="));
343 if(position <= 0) // not found
348 QString recname = line.mid(0, position - QString("=").length()).trimmed();
349 QString recval = line.mid(position + QString("=").length()).trimmed();
352 QtNetworkSettingsRecord *entry = new QtNetworkSettingsRecord(recname, recval);
353 entries.insert(entry->recordName(), entry);
355 } while (!line.isNull());
358 return bTestSettingsLoaded = true;
365 QHash<QString, QtNetworkSettingsRecord* > QtNetworkSettings::entries = QHash<QString, QtNetworkSettingsRecord* > ();
366 bool QtNetworkSettings::bDefaultIapLoaded = false;
367 bool QtNetworkSettings::bTestSettingsLoaded = false;
368 QString QtNetworkSettings::iapFileFullPath = QString("C:\\Data\\iap.txt");
369 QByteArray QtNetworkSettings::serverIp;
370 QByteArray QtNetworkSettings::imapExpectedReply;
371 QByteArray QtNetworkSettings::imapExpectedReplySsl;
375 #define Q_SET_DEFAULT_IAP QtNetworkSettings::setDefaultIap();
377 #define Q_SET_DEFAULT_IAP
380 #ifdef QT_NETWORK_LIB
381 class QtNetworkSettingsInitializerCode {
383 QtNetworkSettingsInitializerCode() {
386 // We have a non-trivial constructor in global static.
387 // The QtNetworkSettings::serverName() uses native API which assumes
388 // Cleanup-stack to exist. That's why we create it here and install
389 // top level TRAP harness.
390 CTrapCleanup *cleanupStack = q_check_ptr(CTrapCleanup::New());
392 QHostInfo testServerResult = QHostInfo::fromName(QtNetworkSettings::serverName());
393 if (testServerResult.error() != QHostInfo::NoError) {
394 qWarning() << "Could not lookup" << QtNetworkSettings::serverName();
395 qWarning() << "Please configure the test environment!";
396 qWarning() << "See /etc/hosts or network-settings.h";
402 // In Symbian HW there is no sense to run this check since global statics are
403 // initialized before QTestLib initializes the output channel for QWarnigns.
404 // So if there is problem network setup, also all QtCore etc tests whcih have
405 // QtNetwork dependency will crash with panic "0 - Exiciting"
409 QHostInfo testServerResult = QHostInfo::fromName(QtNetworkSettings::serverName());
410 if (testServerResult.error() != QHostInfo::NoError) {
411 qWarning() << "Could not lookup" << QtNetworkSettings::serverName();
412 qWarning() << "Please configure the test environment!";
413 qWarning() << "See /etc/hosts or network-settings.h";
419 QtNetworkSettingsInitializerCode qtNetworkSettingsInitializer;