1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the test suite of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#include <QString>
43
#ifdef QT_NETWORK_LIB
44
#include <QtNetwork/QHostInfo>
45
#endif
46
47
48
#ifdef Q_OS_SYMBIAN
49
#include <e32base.h>
50
#include <sys/socket.h>
51
#include <net/if.h>
52
#include <QSharedPointer>
53
#include <QHash>
54
#endif
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.
60
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
66
67
// FIXME: any reason we do this for symbian only, and not other platforms?
68
class QtNetworkSettingsRecord {
69
public:
70
    QtNetworkSettingsRecord() { }
71
72
    QtNetworkSettingsRecord(const QString& recName, const QString& recVal)
73
        : strRecordName(recName), strRecordValue(recVal) { }
74
75
    QtNetworkSettingsRecord(const QtNetworkSettingsRecord & other)
76
         : strRecordName(other.strRecordName), strRecordValue(other.strRecordValue) { }
77
78
    ~QtNetworkSettingsRecord() { }
79
80
    const QString& recordName() const { return strRecordName; }
81
    const QString& recordValue() const { return strRecordValue; }
82
83
private:
84
    QString strRecordName;
85
    QString strRecordValue;
86
};
87
88
#endif // Q_OS_SYMBIAN
89
90
class QtNetworkSettings
91
{
92
public:
93
94
    static QString serverLocalName()
95
    {
96
#ifdef Q_OS_SYMBIAN
97
        loadTestSettings();
98
99
        if(QtNetworkSettings::entries.contains("server.localname")) {
100
            QtNetworkSettingsRecord* entry = entries["server.localname"];
101
            return entry->recordValue();
102
        }
103
#endif
104
        return QString("qt-test-server");
105
    }
106
    static QString serverDomainName()
107
    {
108
#ifdef Q_OS_SYMBIAN
109
        loadTestSettings();
110
111
        if(QtNetworkSettings::entries.contains("server.domainname")) {
112
            QtNetworkSettingsRecord* entry = entries["server.domainname"];
113
            return entry->recordValue();
114
        }
115
#endif
116
        return QString("qt-test-net");
117
    }
118
    static QString serverName()
119
    {
120
#ifdef Q_OS_SYMBIAN
121
        loadTestSettings();
122
#endif
123
        return serverLocalName() + "." + serverDomainName();
124
    }
125
    static QString winServerName()
126
    {
127
        return serverName();
128
    }
129
    static QString wildcardServerName()
130
    {
131
        return "qt-test-server.wildcard.dev." + serverDomainName();
132
    }
133
134
#ifdef QT_NETWORK_LIB
135
    static QHostAddress serverIP()
136
    {
137
#ifdef Q_OS_SYMBIAN
138
        loadTestSettings();
139
140
        if(QtNetworkSettings::entries.contains("server.ip")) {
141
            QtNetworkSettingsRecord* entry = entries["server.ip"];
142
            if(serverIp.isNull()) {
143
                serverIp = entry->recordValue().toAscii();
144
            }
145
            return QHostAddress(serverIp.data());
146
        }
147
#endif // Q_OS_SYMBIAN
148
    return QHostInfo::fromName(serverName()).addresses().first();
149
    }
150
#endif
151
152
    static bool compareReplyIMAP(QByteArray const& actual)
153
    {
154
        QList<QByteArray> expected;
155
156
#ifdef Q_OS_SYMBIAN
157
        loadTestSettings();
158
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');
164
            }
165
            expected << imapExpectedReply.data();
166
        }
167
#endif
168
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");
173
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");
178
179
        // Feel free to add more as needed
180
181
        Q_FOREACH (QByteArray const& ba, expected) {
182
            if (ba == actual) {
183
                return true;
184
            }
185
        }
186
187
        return false;
188
    }
189
190
    static bool compareReplyIMAPSSL(QByteArray const& actual)
191
    {
192
        QList<QByteArray> expected;
193
194
#ifdef Q_OS_SYMBIAN
195
        loadTestSettings();
196
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');
202
            }
203
            expected << imapExpectedReplySsl.data();
204
        }
205
#endif
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");
210
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");
215
216
        // Feel free to add more as needed
217
218
        Q_FOREACH (QByteArray const& ba, expected) {
219
            if (ba == actual) {
220
                return true;
221
            }
222
        }
223
224
        return false;
225
    }
226
227
    static bool compareReplyFtp(QByteArray const& actual)
228
    {
229
        QList<QByteArray> expected;
230
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" );
235
236
        Q_FOREACH (QByteArray const& ba, expected) {
237
            if (ba == actual) {
238
                return true;
239
            }
240
        }
241
242
        return false;
243
    }
244
245
#ifdef Q_OS_SYMBIAN
246
    static void setDefaultIap()
247
    {
248
        loadDefaultIap();
249
250
        struct ifreq ifReq;
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());
255
        }
256
        else // some default value
257
            strcpy( ifReq.ifr_name, "Lab");
258
259
        int err = setdefaultif( &ifReq );
260
        if(err)
261
            printf("Setting default IAP - '%s' failed: %d\n", ifReq.ifr_name, err);
262
        else
263
            printf("'%s' used as an default IAP\n", ifReq.ifr_name);
264
    }
265
#endif
266
267
private:
268
269
#ifdef Q_OS_SYMBIAN
270
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;
278
279
    static bool loadDefaultIap() {
280
        if(bDefaultIapLoaded)
281
            return true;
282
283
        QFile iapCfgFile(iapFileFullPath);
284
285
        bool bFoundDefaultIapTag = false;
286
287
        if (iapCfgFile.open(QFile::ReadOnly)) {
288
            QTextStream input(&iapCfgFile);
289
            QString line;
290
            do {
291
                line = input.readLine().trimmed();
292
                if(line.startsWith(QString("#")))
293
                    continue; // comment found
294
295
                if(line.contains(QString("[DEFAULT]"))) {
296
                    bFoundDefaultIapTag = true;
297
                } else if(line.contains(QString("[")) && bFoundDefaultIapTag) {
298
                    break;
299
                }
300
301
                if(bFoundDefaultIapTag && line.contains("name")) {
302
                    int position = line.indexOf(QString("="));
303
                    position += QString("=").length();
304
305
                    //create record
306
                    QtNetworkSettingsRecord *entry =
307
                        new QtNetworkSettingsRecord( QString("iap.default"), line.mid(position).trimmed() );
308
                    entries.insert(entry->recordName(), entry);
309
                    break;
310
                }
311
            } while (!line.isNull());
312
        }
313
314
        return bDefaultIapLoaded = bFoundDefaultIapTag;
315
    }
316
317
    static bool loadTestSettings() {
318
        if(bTestSettingsLoaded)
319
            return true;
320
321
        QFile cfgFile(iapFileFullPath);
322
        bool bFoundTestTag = false;
323
324
        if (cfgFile.open(QFile::ReadOnly)) {
325
            QTextStream input(&cfgFile);
326
            QString line;
327
            do {
328
                line = input.readLine().trimmed();
329
330
                if(line.startsWith(QString("#")) || line.length() == 0)
331
                    continue; // comment or empty line found
332
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
338
                }
339
340
                if(bFoundTestTag) { // non-empty line
341
                    int position = line.indexOf(QString("="));
342
343
                    if(position <= 0) // not found
344
                        continue;
345
346
                    // found - extract
347
348
                    QString recname = line.mid(0, position - QString("=").length()).trimmed();
349
                    QString recval = line.mid(position + QString("=").length()).trimmed();
350
351
                    //create record
352
                    QtNetworkSettingsRecord *entry = new QtNetworkSettingsRecord(recname, recval);
353
                    entries.insert(entry->recordName(), entry);
354
                }
355
            } while (!line.isNull());
356
        }
357
358
        return bTestSettingsLoaded = true;
359
    }
360
#endif
361
362
363
};
364
#ifdef Q_OS_SYMBIAN
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;
372
#endif
373
374
#ifdef Q_OS_SYMBIAN
375
#define Q_SET_DEFAULT_IAP QtNetworkSettings::setDefaultIap();
376
#else
377
#define Q_SET_DEFAULT_IAP
378
#endif
379
380
#ifdef QT_NETWORK_LIB
381
class QtNetworkSettingsInitializerCode {
382
public:
383
    QtNetworkSettingsInitializerCode() {
384
#ifdef Q_OS_SYMBIAN
385
#ifdef Q_CC_NOKIAX86
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());
391
        TRAPD(err,
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";
397
                qFatal("Exiting");
398
            }
399
        )
400
        delete cleanupStack;
401
//#else
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"
406
#endif
407
408
#else
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";
414
            qFatal("Exiting");
415
        }
416
#endif
417
    }
418
};
419
QtNetworkSettingsInitializerCode qtNetworkSettingsInitializer;
420
#endif