| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org> |
| 4 | ** Copyright (C) 2016 Intel Corporation. |
| 5 | ** Contact: https://www.qt.io/licensing/ |
| 6 | ** |
| 7 | ** This file is part of the test suite of the Qt Toolkit. |
| 8 | ** |
| 9 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| 10 | ** Commercial License Usage |
| 11 | ** Licensees holding valid commercial Qt licenses may use this file in |
| 12 | ** accordance with the commercial license agreement provided with the |
| 13 | ** Software or, alternatively, in accordance with the terms contained in |
| 14 | ** a written agreement between you and The Qt Company. For licensing terms |
| 15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
| 16 | ** information use the contact form at https://www.qt.io/contact-us. |
| 17 | ** |
| 18 | ** GNU General Public License Usage |
| 19 | ** Alternatively, this file may be used under the terms of the GNU |
| 20 | ** General Public License version 3 as published by the Free Software |
| 21 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| 22 | ** included in the packaging of this file. Please review the following |
| 23 | ** information to ensure the GNU General Public License requirements will |
| 24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| 25 | ** |
| 26 | ** $QT_END_LICENSE$ |
| 27 | ** |
| 28 | ****************************************************************************/ |
| 29 | |
| 30 | |
| 31 | #include <QtTest/QtTest> |
| 32 | #include <QtNetwork/QDnsLookup> |
| 33 | #include <QtNetwork/QHostAddress> |
| 34 | |
| 35 | static const int Timeout = 15000; // 15s |
| 36 | |
| 37 | class tst_QDnsLookup: public QObject |
| 38 | { |
| 39 | Q_OBJECT |
| 40 | |
| 41 | QString domainName(const QString &input); |
| 42 | QString domainNameList(const QString &input); |
| 43 | QStringList domainNameListAlternatives(const QString &input); |
| 44 | public slots: |
| 45 | void initTestCase(); |
| 46 | |
| 47 | private slots: |
| 48 | void lookup_data(); |
| 49 | void lookup(); |
| 50 | void lookupReuse(); |
| 51 | void lookupAbortRetry(); |
| 52 | }; |
| 53 | |
| 54 | void tst_QDnsLookup::initTestCase() |
| 55 | { |
| 56 | QTest::addColumn<QString>(name: "tld" ); |
| 57 | QTest::newRow(dataTag: "normal" ) << ".test.qt-project.org" ; |
| 58 | QTest::newRow(dataTag: "idn" ) << ".alqualond\xc3\xab.test.qt-project.org" ; |
| 59 | } |
| 60 | |
| 61 | QString tst_QDnsLookup::domainName(const QString &input) |
| 62 | { |
| 63 | if (input.isEmpty()) |
| 64 | return input; |
| 65 | |
| 66 | if (input.endsWith(c: QLatin1Char('.'))) { |
| 67 | QString nodot = input; |
| 68 | nodot.chop(n: 1); |
| 69 | return nodot; |
| 70 | } |
| 71 | |
| 72 | QFETCH_GLOBAL(QString, tld); |
| 73 | return input + tld; |
| 74 | } |
| 75 | |
| 76 | QString tst_QDnsLookup::domainNameList(const QString &input) |
| 77 | { |
| 78 | QStringList list = input.split(sep: QLatin1Char(';')); |
| 79 | QString result; |
| 80 | foreach (const QString &s, list) { |
| 81 | if (!result.isEmpty()) |
| 82 | result += ';'; |
| 83 | result += domainName(input: s); |
| 84 | } |
| 85 | return result; |
| 86 | } |
| 87 | |
| 88 | QStringList tst_QDnsLookup::domainNameListAlternatives(const QString &input) |
| 89 | { |
| 90 | QStringList alternatives = input.split(sep: '|'); |
| 91 | for (int i = 0; i < alternatives.length(); ++i) |
| 92 | alternatives[i] = domainNameList(input: alternatives[i]); |
| 93 | return alternatives; |
| 94 | } |
| 95 | |
| 96 | void tst_QDnsLookup::lookup_data() |
| 97 | { |
| 98 | QTest::addColumn<int>(name: "type" ); |
| 99 | QTest::addColumn<QString>(name: "domain" ); |
| 100 | QTest::addColumn<int>(name: "error" ); |
| 101 | QTest::addColumn<QString>(name: "cname" ); |
| 102 | QTest::addColumn<QString>(name: "host" ); |
| 103 | QTest::addColumn<QString>(name: "mx" ); |
| 104 | QTest::addColumn<QString>(name: "ns" ); |
| 105 | QTest::addColumn<QString>(name: "ptr" ); |
| 106 | QTest::addColumn<QString>(name: "srv" ); |
| 107 | QTest::addColumn<QString>(name: "txt" ); |
| 108 | |
| 109 | QTest::newRow(dataTag: "a-empty" ) << int(QDnsLookup::A) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 110 | QTest::newRow(dataTag: "a-notfound" ) << int(QDnsLookup::A) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 111 | QTest::newRow(dataTag: "a-single" ) << int(QDnsLookup::A) << "a-single" << int(QDnsLookup::NoError) << "" << "192.0.2.1" << "" << "" << "" << "" << "" ; |
| 112 | QTest::newRow(dataTag: "a-multi" ) << int(QDnsLookup::A) << "a-multi" << int(QDnsLookup::NoError) << "" << "192.0.2.1;192.0.2.2;192.0.2.3" << "" << "" << "" << "" << "" ; |
| 113 | QTest::newRow(dataTag: "aaaa-empty" ) << int(QDnsLookup::AAAA) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 114 | QTest::newRow(dataTag: "aaaa-notfound" ) << int(QDnsLookup::AAAA) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 115 | QTest::newRow(dataTag: "aaaa-single" ) << int(QDnsLookup::AAAA) << "aaaa-single" << int(QDnsLookup::NoError) << "" << "2001:db8::1" << "" << "" << "" << "" << "" ; |
| 116 | QTest::newRow(dataTag: "aaaa-multi" ) << int(QDnsLookup::AAAA) << "aaaa-multi" << int(QDnsLookup::NoError) << "" << "2001:db8::1;2001:db8::2;2001:db8::3" << "" << "" << "" << "" << "" ; |
| 117 | |
| 118 | QTest::newRow(dataTag: "any-empty" ) << int(QDnsLookup::ANY) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 119 | QTest::newRow(dataTag: "any-notfound" ) << int(QDnsLookup::ANY) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 120 | QTest::newRow(dataTag: "any-a-single" ) << int(QDnsLookup::ANY) << "a-single" << int(QDnsLookup::NoError) << "" << "192.0.2.1" << "" << "" << "" << "" << "" ; |
| 121 | QTest::newRow(dataTag: "any-a-plus-aaaa" ) << int(QDnsLookup::ANY) << "a-plus-aaaa" << int(QDnsLookup::NoError) << "" << "198.51.100.1;2001:db8::1:1" << "" << "" << "" << "" << "" ; |
| 122 | QTest::newRow(dataTag: "any-multi" ) << int(QDnsLookup::ANY) << "multi" << int(QDnsLookup::NoError) << "" << "198.51.100.1;198.51.100.2;198.51.100.3;2001:db8::1:1;2001:db8::1:2" << "" << "" << "" << "" << "" ; |
| 123 | |
| 124 | QTest::newRow(dataTag: "mx-empty" ) << int(QDnsLookup::MX) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 125 | QTest::newRow(dataTag: "mx-notfound" ) << int(QDnsLookup::MX) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 126 | QTest::newRow(dataTag: "mx-single" ) << int(QDnsLookup::MX) << "mx-single" << int(QDnsLookup::NoError) << "" << "" << "10 multi" << "" << "" << "" << "" ; |
| 127 | QTest::newRow(dataTag: "mx-single-cname" ) << int(QDnsLookup::MX) << "mx-single-cname" << int(QDnsLookup::NoError) << "" << "" << "10 cname" << "" << "" << "" << "" ; |
| 128 | QTest::newRow(dataTag: "mx-multi" ) << int(QDnsLookup::MX) << "mx-multi" << int(QDnsLookup::NoError) << "" << "" << "10 multi;20 a-single" << "" << "" << "" << "" ; |
| 129 | QTest::newRow(dataTag: "mx-multi-sameprio" ) << int(QDnsLookup::MX) << "mx-multi-sameprio" << int(QDnsLookup::NoError) << "" << "" |
| 130 | << "10 multi;10 a-single|" |
| 131 | "10 a-single;10 multi" << "" << "" << "" << "" ; |
| 132 | |
| 133 | QTest::newRow(dataTag: "ns-empty" ) << int(QDnsLookup::NS) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 134 | QTest::newRow(dataTag: "ns-notfound" ) << int(QDnsLookup::NS) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 135 | QTest::newRow(dataTag: "ns-single" ) << int(QDnsLookup::NS) << "ns-single" << int(QDnsLookup::NoError) << "" << "" << "" << "ns11.cloudns.net." << "" << "" << "" ; |
| 136 | QTest::newRow(dataTag: "ns-multi" ) << int(QDnsLookup::NS) << "ns-multi" << int(QDnsLookup::NoError) << "" << "" << "" << "ns11.cloudns.net.;ns12.cloudns.net." << "" << "" << "" ; |
| 137 | |
| 138 | QTest::newRow(dataTag: "ptr-empty" ) << int(QDnsLookup::PTR) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 139 | QTest::newRow(dataTag: "ptr-notfound" ) << int(QDnsLookup::PTR) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 140 | #if 0 |
| 141 | // temporarily disabled since the new hosting provider can't insert |
| 142 | // PTR records outside of the in-addr.arpa zone |
| 143 | QTest::newRow("ptr-single" ) << int(QDnsLookup::PTR) << "ptr-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "a-single" << "" << "" ; |
| 144 | #endif |
| 145 | |
| 146 | QTest::newRow(dataTag: "srv-empty" ) << int(QDnsLookup::SRV) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 147 | QTest::newRow(dataTag: "srv-notfound" ) << int(QDnsLookup::SRV) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 148 | QTest::newRow(dataTag: "srv-single" ) << int(QDnsLookup::SRV) << "_echo._tcp.srv-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "5 0 7 multi" << "" ; |
| 149 | QTest::newRow(dataTag: "srv-prio" ) << int(QDnsLookup::SRV) << "_echo._tcp.srv-prio" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "1 0 7 multi;2 0 7 a-plus-aaaa" << "" ; |
| 150 | QTest::newRow(dataTag: "srv-weighted" ) << int(QDnsLookup::SRV) << "_echo._tcp.srv-weighted" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" |
| 151 | << "5 75 7 multi;5 25 7 a-plus-aaaa|" |
| 152 | "5 25 7 a-plus-aaaa;5 75 7 multi" << "" ; |
| 153 | QTest::newRow(dataTag: "srv-multi" ) << int(QDnsLookup::SRV) << "_echo._tcp.srv-multi" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" |
| 154 | << "1 50 7 multi;2 50 7 a-single;2 50 7 aaaa-single;3 50 7 a-multi|" |
| 155 | "1 50 7 multi;2 50 7 aaaa-single;2 50 7 a-single;3 50 7 a-multi" << "" ; |
| 156 | |
| 157 | QTest::newRow(dataTag: "txt-empty" ) << int(QDnsLookup::TXT) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "" ; |
| 158 | QTest::newRow(dataTag: "txt-notfound" ) << int(QDnsLookup::TXT) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "" ; |
| 159 | QTest::newRow(dataTag: "txt-single" ) << int(QDnsLookup::TXT) << "txt-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "" << "Hello" ; |
| 160 | QTest::newRow(dataTag: "txt-multi-onerr" ) << int(QDnsLookup::TXT) << "txt-multi-onerr" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "" |
| 161 | << QString::fromLatin1(str: "Hello\0World" , size: sizeof("Hello\0World" ) - 1); |
| 162 | QTest::newRow(dataTag: "txt-multi-multirr" ) << int(QDnsLookup::TXT) << "txt-multi-multirr" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "" << "Hello;World" ; |
| 163 | } |
| 164 | |
| 165 | static QByteArray msgDnsLookup(QDnsLookup::Error actualError, |
| 166 | int expectedError, |
| 167 | const QString &domain, |
| 168 | const QString &cname, |
| 169 | const QString &host, |
| 170 | const QString &srv, |
| 171 | const QString &mx, |
| 172 | const QString &ns, |
| 173 | const QString &ptr, |
| 174 | const QString &errorString) |
| 175 | { |
| 176 | QString result; |
| 177 | QTextStream str(&result); |
| 178 | str << "Actual error: " << actualError; |
| 179 | if (!errorString.isEmpty()) |
| 180 | str << " (" << errorString << ')'; |
| 181 | str << ", expected: " << expectedError; |
| 182 | str << ", domain: " << domain; |
| 183 | if (!cname.isEmpty()) |
| 184 | str << ", cname: " << cname; |
| 185 | str << ", host: " << host; |
| 186 | if (!srv.isEmpty()) |
| 187 | str << " server: " << srv; |
| 188 | if (!mx.isEmpty()) |
| 189 | str << " mx: " << mx; |
| 190 | if (!ns.isEmpty()) |
| 191 | str << " ns: " << ns; |
| 192 | if (!ptr.isEmpty()) |
| 193 | str << " ptr: " << ptr; |
| 194 | return result.toLocal8Bit(); |
| 195 | } |
| 196 | |
| 197 | void tst_QDnsLookup::lookup() |
| 198 | { |
| 199 | QFETCH(int, type); |
| 200 | QFETCH(QString, domain); |
| 201 | QFETCH(int, error); |
| 202 | QFETCH(QString, cname); |
| 203 | QFETCH(QString, host); |
| 204 | QFETCH(QString, mx); |
| 205 | QFETCH(QString, ns); |
| 206 | QFETCH(QString, ptr); |
| 207 | QFETCH(QString, srv); |
| 208 | QFETCH(QString, txt); |
| 209 | |
| 210 | // transform the inputs |
| 211 | domain = domainName(input: domain); |
| 212 | cname = domainName(input: cname); |
| 213 | ns = domainNameList(input: ns); |
| 214 | ptr = domainNameList(input: ptr); |
| 215 | |
| 216 | // SRV and MX have reply entries that can change order |
| 217 | // and we can't sort |
| 218 | QStringList mx_alternatives = domainNameListAlternatives(input: mx); |
| 219 | QStringList srv_alternatives = domainNameListAlternatives(input: srv); |
| 220 | |
| 221 | QDnsLookup lookup; |
| 222 | lookup.setType(static_cast<QDnsLookup::Type>(type)); |
| 223 | lookup.setName(domain); |
| 224 | lookup.lookup(); |
| 225 | QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); |
| 226 | |
| 227 | #if defined(Q_OS_ANDROID) |
| 228 | if (lookup.errorString() == QStringLiteral("Not yet supported on Android" )) |
| 229 | QEXPECT_FAIL("" , "Not yet supported on Android" , Abort); |
| 230 | #endif |
| 231 | |
| 232 | QVERIFY2(int(lookup.error()) == error, |
| 233 | msgDnsLookup(lookup.error(), error, domain, cname, host, srv, mx, ns, ptr, lookup.errorString())); |
| 234 | if (error == QDnsLookup::NoError) |
| 235 | QVERIFY(lookup.errorString().isEmpty()); |
| 236 | QCOMPARE(int(lookup.type()), type); |
| 237 | QCOMPARE(lookup.name(), domain); |
| 238 | |
| 239 | // canonical names |
| 240 | if (!cname.isEmpty()) { |
| 241 | QVERIFY(!lookup.canonicalNameRecords().isEmpty()); |
| 242 | const QDnsDomainNameRecord cnameRecord = lookup.canonicalNameRecords().first(); |
| 243 | QCOMPARE(cnameRecord.name(), domain); |
| 244 | QCOMPARE(cnameRecord.value(), cname); |
| 245 | } else { |
| 246 | QVERIFY(lookup.canonicalNameRecords().isEmpty()); |
| 247 | } |
| 248 | |
| 249 | // host addresses |
| 250 | const QString hostName = cname.isEmpty() ? domain : cname; |
| 251 | QStringList addresses; |
| 252 | foreach (const QDnsHostAddressRecord &record, lookup.hostAddressRecords()) { |
| 253 | //reply may include A & AAAA records for nameservers, ignore them and only look at records matching the query |
| 254 | if (record.name() == hostName) |
| 255 | addresses << record.value().toString().toLower(); |
| 256 | } |
| 257 | addresses.sort(); |
| 258 | QCOMPARE(addresses.join(';'), host); |
| 259 | |
| 260 | // mail exchanges |
| 261 | QStringList mailExchanges; |
| 262 | foreach (const QDnsMailExchangeRecord &record, lookup.mailExchangeRecords()) { |
| 263 | QCOMPARE(record.name(), domain); |
| 264 | mailExchanges << QString::number(record.preference()) + QLatin1Char(' ') + record.exchange(); |
| 265 | } |
| 266 | QVERIFY2(mx_alternatives.contains(mailExchanges.join(';')), |
| 267 | qPrintable("Actual: " + mailExchanges.join(';') + "\nExpected one of:\n" + mx_alternatives.join('\n'))); |
| 268 | |
| 269 | // name servers |
| 270 | QStringList nameServers; |
| 271 | foreach (const QDnsDomainNameRecord &record, lookup.nameServerRecords()) { |
| 272 | //reply may include NS records for authoritative nameservers, ignore them and only look at records matching the query |
| 273 | if (record.name() == domain) |
| 274 | nameServers << record.value(); |
| 275 | } |
| 276 | nameServers.sort(); |
| 277 | QCOMPARE(nameServers.join(';'), ns); |
| 278 | |
| 279 | // pointers |
| 280 | if (!ptr.isEmpty()) { |
| 281 | QVERIFY(!lookup.pointerRecords().isEmpty()); |
| 282 | const QDnsDomainNameRecord ptrRecord = lookup.pointerRecords().first(); |
| 283 | QCOMPARE(ptrRecord.name(), domain); |
| 284 | QCOMPARE(ptrRecord.value(), ptr); |
| 285 | } else { |
| 286 | QVERIFY(lookup.pointerRecords().isEmpty()); |
| 287 | } |
| 288 | |
| 289 | // services |
| 290 | QStringList services; |
| 291 | foreach (const QDnsServiceRecord &record, lookup.serviceRecords()) { |
| 292 | QCOMPARE(record.name(), domain); |
| 293 | services << (QString::number(record.priority()) + QLatin1Char(' ') |
| 294 | + QString::number(record.weight()) + QLatin1Char(' ') |
| 295 | + QString::number(record.port()) + QLatin1Char(' ') + record.target()); |
| 296 | } |
| 297 | QVERIFY2(srv_alternatives.contains(services.join(';')), |
| 298 | qPrintable("Actual: " + services.join(';') + "\nExpected one of:\n" + srv_alternatives.join('\n'))); |
| 299 | |
| 300 | // text |
| 301 | QStringList texts; |
| 302 | foreach (const QDnsTextRecord &record, lookup.textRecords()) { |
| 303 | QCOMPARE(record.name(), domain); |
| 304 | QString text; |
| 305 | foreach (const QByteArray &ba, record.values()) { |
| 306 | if (!text.isEmpty()) |
| 307 | text += '\0'; |
| 308 | text += QString::fromLatin1(str: ba); |
| 309 | } |
| 310 | texts << text; |
| 311 | } |
| 312 | texts.sort(); |
| 313 | QCOMPARE(texts.join(';'), txt); |
| 314 | } |
| 315 | |
| 316 | void tst_QDnsLookup::lookupReuse() |
| 317 | { |
| 318 | QDnsLookup lookup; |
| 319 | |
| 320 | // first lookup |
| 321 | lookup.setType(QDnsLookup::A); |
| 322 | lookup.setName(domainName(input: "a-single" )); |
| 323 | lookup.lookup(); |
| 324 | QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); |
| 325 | |
| 326 | #if defined(Q_OS_ANDROID) |
| 327 | if (lookup.errorString() == QStringLiteral("Not yet supported on Android" )) |
| 328 | QEXPECT_FAIL("" , "Not yet supported on Android" , Abort); |
| 329 | #endif |
| 330 | |
| 331 | QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError)); |
| 332 | QVERIFY(!lookup.hostAddressRecords().isEmpty()); |
| 333 | QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("a-single" )); |
| 334 | QCOMPARE(lookup.hostAddressRecords().first().value(), QHostAddress("192.0.2.1" )); |
| 335 | |
| 336 | // second lookup |
| 337 | lookup.setType(QDnsLookup::AAAA); |
| 338 | lookup.setName(domainName(input: "aaaa-single" )); |
| 339 | lookup.lookup(); |
| 340 | QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); |
| 341 | QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError)); |
| 342 | QVERIFY(!lookup.hostAddressRecords().isEmpty()); |
| 343 | QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("aaaa-single" )); |
| 344 | QCOMPARE(lookup.hostAddressRecords().first().value(), QHostAddress("2001:db8::1" )); |
| 345 | } |
| 346 | |
| 347 | |
| 348 | void tst_QDnsLookup::lookupAbortRetry() |
| 349 | { |
| 350 | QDnsLookup lookup; |
| 351 | |
| 352 | // try and abort the lookup |
| 353 | lookup.setType(QDnsLookup::A); |
| 354 | lookup.setName(domainName(input: "a-single" )); |
| 355 | lookup.lookup(); |
| 356 | lookup.abort(); |
| 357 | QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); |
| 358 | QCOMPARE(int(lookup.error()), int(QDnsLookup::OperationCancelledError)); |
| 359 | QVERIFY(lookup.hostAddressRecords().isEmpty()); |
| 360 | |
| 361 | // retry a different lookup |
| 362 | lookup.setType(QDnsLookup::AAAA); |
| 363 | lookup.setName(domainName(input: "aaaa-single" )); |
| 364 | lookup.lookup(); |
| 365 | QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout); |
| 366 | |
| 367 | #if defined(Q_OS_ANDROID) |
| 368 | if (lookup.errorString() == QStringLiteral("Not yet supported on Android" )) |
| 369 | QEXPECT_FAIL("" , "Not yet supported on Android" , Abort); |
| 370 | #endif |
| 371 | |
| 372 | QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError)); |
| 373 | QVERIFY(!lookup.hostAddressRecords().isEmpty()); |
| 374 | QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("aaaa-single" )); |
| 375 | QCOMPARE(lookup.hostAddressRecords().first().value(), QHostAddress("2001:db8::1" )); |
| 376 | } |
| 377 | |
| 378 | QTEST_MAIN(tst_QDnsLookup) |
| 379 | #include "tst_qdnslookup.moc" |
| 380 | |