1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include "../qbearertestcommon.h"
31
32#ifndef QT_NO_BEARERMANAGEMENT
33#include <QtNetwork/qnetworkconfiguration.h>
34#include <QtNetwork/qnetworkconfigmanager.h>
35#endif
36
37QT_USE_NAMESPACE
38class tst_QNetworkConfigurationManager : public QObject
39{
40 Q_OBJECT
41
42private slots:
43#ifndef QT_NO_BEARERMANAGEMENT
44 void usedInThread(); // this test must be first, or it will falsely pass
45 void allConfigurations();
46 void defaultConfiguration();
47 void configurationFromIdentifier();
48#endif
49};
50
51#ifndef QT_NO_BEARERMANAGEMENT
52void printConfigurationDetails(const QNetworkConfiguration& p)
53{
54 qDebug() << p.name() <<": isvalid->" <<p.isValid() << " type->"<< p.type() <<
55 " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() <<
56 " purpose->" << p.purpose() << " state->" << p.state();
57}
58
59void tst_QNetworkConfigurationManager::allConfigurations()
60{
61 QNetworkConfigurationManager manager;
62 QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations();
63
64 foreach(QNetworkConfiguration c, preScanConfigs)
65 {
66 QVERIFY2(c.type()!=QNetworkConfiguration::UserChoice, "allConfiguration must not return UserChoice configs");
67 }
68
69 QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
70 manager.updateConfigurations(); //initiate scans
71 QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete
72
73 QList<QNetworkConfiguration> configs = manager.allConfigurations();
74
75 int all = configs.count();
76 qDebug() << "All configurations:" << all;
77 QVERIFY(all);
78 foreach(QNetworkConfiguration p, configs) {
79 QVERIFY(p.isValid());
80 printConfigurationDetails(p);
81 QVERIFY(p.type() != QNetworkConfiguration::Invalid);
82 QVERIFY(p.type() != QNetworkConfiguration::UserChoice);
83 }
84
85 configs = manager.allConfigurations(flags: QNetworkConfiguration::Undefined);
86 int undefined = configs.count();
87 QVERIFY(undefined <= all);
88 qDebug() << "Undefined configurations:" << undefined;
89 foreach( const QNetworkConfiguration p, configs) {
90 printConfigurationDetails(p);
91 QVERIFY(p.state() & QNetworkConfiguration::Undefined);
92 QVERIFY(!(p.state() & QNetworkConfiguration::Defined));
93 }
94
95 //get defined configs only (same as all)
96 configs = manager.allConfigurations(flags: QNetworkConfiguration::Defined);
97 int defined = configs.count();
98 qDebug() << "Defined configurations:" << defined;
99 QVERIFY(defined <= all);
100 foreach( const QNetworkConfiguration p, configs) {
101 printConfigurationDetails(p);
102 QVERIFY(p.state() & QNetworkConfiguration::Defined);
103 QVERIFY(!(p.state() & QNetworkConfiguration::Undefined));
104 }
105
106 //get discovered configurations only
107 configs = manager.allConfigurations(flags: QNetworkConfiguration::Discovered);
108 int discovered = configs.count();
109 //QVERIFY(discovered);
110 qDebug() << "Discovered configurations:" << discovered;
111 foreach(const QNetworkConfiguration p, configs) {
112 printConfigurationDetails(p);
113 QVERIFY(p.isValid());
114 QVERIFY(!(p.state() & QNetworkConfiguration::Undefined));
115 QVERIFY(p.state() & QNetworkConfiguration::Defined);
116 QVERIFY(p.state() & QNetworkConfiguration::Discovered);
117 }
118
119 //getactive configurations only
120 configs = manager.allConfigurations(flags: QNetworkConfiguration::Active);
121 int active = configs.count();
122 if (active)
123 QVERIFY(manager.isOnline());
124 else
125 QVERIFY(!manager.isOnline());
126
127 //QVERIFY(active);
128 qDebug() << "Active configurations:" << active;
129 foreach(const QNetworkConfiguration p, configs) {
130 printConfigurationDetails(p);
131 QVERIFY(p.isValid());
132 QVERIFY(!(p.state() & QNetworkConfiguration::Undefined));
133 QVERIFY(p.state() & QNetworkConfiguration::Active);
134 QVERIFY(p.state() & QNetworkConfiguration::Discovered);
135 QVERIFY(p.state() & QNetworkConfiguration::Defined);
136 }
137
138 QVERIFY(all >= discovered);
139 QVERIFY(discovered >= active);
140}
141
142
143void tst_QNetworkConfigurationManager::defaultConfiguration()
144{
145 QNetworkConfigurationManager manager;
146 QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
147 manager.updateConfigurations(); //initiate scans
148 QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete
149
150 QList<QNetworkConfiguration> configs = manager.allConfigurations();
151 QNetworkConfiguration defaultConfig = manager.defaultConfiguration();
152
153 bool confirm = configs.contains(t: defaultConfig);
154
155 if (defaultConfig.type() != QNetworkConfiguration::UserChoice) {
156 QVERIFY(confirm || !defaultConfig.isValid());
157 QVERIFY(!(confirm && !defaultConfig.isValid()));
158 } else {
159 QVERIFY(!confirm); // user choice config is not part of allConfigurations()
160 QVERIFY(defaultConfig.isValid());
161 QCOMPARE(defaultConfig.name(), QString("UserChoice"));
162 QCOMPARE(defaultConfig.children().count(), 0);
163 QVERIFY(!defaultConfig.isRoamingAvailable());
164 QCOMPARE(defaultConfig.state(), QNetworkConfiguration::Discovered);
165 QNetworkConfiguration copy = manager.configurationFromIdentifier(identifier: defaultConfig.identifier());
166 QCOMPARE(copy, defaultConfig);
167 }
168}
169
170void tst_QNetworkConfigurationManager::configurationFromIdentifier()
171{
172 QNetworkConfigurationManager manager;
173 QSet<QString> allIdentifier;
174
175 //force an update to get maximum number of configs
176 QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
177 manager.updateConfigurations(); //initiate scans
178 QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete
179
180 QList<QNetworkConfiguration> configs = manager.allConfigurations();
181
182 foreach(QNetworkConfiguration c, configs) {
183 QVERIFY(!allIdentifier.contains(c.identifier()));
184 allIdentifier.insert(value: c.identifier());
185
186 QNetworkConfiguration direct = manager.configurationFromIdentifier(identifier: c.identifier());
187 QVERIFY(direct.isValid());
188 QCOMPARE(direct, c);
189 }
190
191 //assume that there is no item with identifier 'FooBar'
192 QVERIFY(!allIdentifier.contains("FooBar"));
193 QNetworkConfiguration invalid = manager.configurationFromIdentifier(identifier: "FooBar");
194 QVERIFY(!invalid.isValid());
195}
196
197class QNCMTestThread : public QThread
198{
199protected:
200 virtual void run()
201 {
202 QNetworkConfigurationManager manager;
203 preScanConfigs = manager.allConfigurations();
204 QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
205 manager.updateConfigurations(); //initiate scans
206 QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete
207 configs = manager.allConfigurations();
208 }
209public:
210 QList<QNetworkConfiguration> configs;
211 QList<QNetworkConfiguration> preScanConfigs;
212};
213
214// regression test for QTBUG-18795
215void tst_QNetworkConfigurationManager::usedInThread()
216{
217#if defined Q_OS_MAC && !defined (QT_NO_COREWLAN)
218 QSKIP("QTBUG-19070 Mac CoreWlan plugin is broken");
219#else
220 QNCMTestThread thread;
221 connect(sender: &thread, SIGNAL(finished()), receiver: &QTestEventLoop::instance(), SLOT(exitLoop()));
222 thread.start();
223 QTestEventLoop::instance().enterLoop(secs: 100); //QTRY_VERIFY_WITH_TIMEOUT could take ~90 seconds to time out in the thread
224 QVERIFY(!QTestEventLoop::instance().timeout());
225 qDebug() << "prescan:" << thread.preScanConfigs.count();
226 qDebug() << "postscan:" << thread.configs.count();
227
228 QNetworkConfigurationManager manager;
229 QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations();
230 QSignalSpy spy(&manager, SIGNAL(updateCompleted()));
231 manager.updateConfigurations(); //initiate scans
232 QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete
233 QList<QNetworkConfiguration> configs = manager.allConfigurations();
234 QCOMPARE(thread.configs, configs);
235 //Don't compare pre scan configs, because these may be cached and therefore give different results
236 //which makes the test unstable. The post scan results should have all configurations every time
237 //QCOMPARE(thread.preScanConfigs, preScanConfigs);
238#endif
239}
240#endif
241
242QTEST_MAIN(tst_QNetworkConfigurationManager)
243#include "tst_qnetworkconfigurationmanager.moc"
244

source code of qtbase/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp