1/****************************************************************************
2**
3** Copyright (C) 2014 Denis Shienkov <denis.shienkov@gmail.com>
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtSerialPort module 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 <QtSerialPort/QSerialPort>
31#include <QtSerialPort/QSerialPortInfo>
32
33#include <QThread>
34
35Q_DECLARE_METATYPE(QSerialPort::SerialPortError);
36Q_DECLARE_METATYPE(QSerialPort::BaudRate);
37Q_DECLARE_METATYPE(QSerialPort::DataBits);
38Q_DECLARE_METATYPE(QSerialPort::Parity);
39Q_DECLARE_METATYPE(QSerialPort::StopBits);
40Q_DECLARE_METATYPE(QSerialPort::FlowControl);
41Q_DECLARE_METATYPE(QIODevice::OpenMode);
42Q_DECLARE_METATYPE(QIODevice::OpenModeFlag);
43Q_DECLARE_METATYPE(Qt::ConnectionType);
44
45class tst_QSerialPort : public QObject
46{
47 Q_OBJECT
48public:
49 explicit tst_QSerialPort();
50
51 static void enterLoop(int secs)
52 {
53 ++loopLevel;
54 QTestEventLoop::instance().enterLoop(secs);
55 --loopLevel;
56 }
57
58 static void enterLoopMsecs(int msecs)
59 {
60 ++loopLevel;
61 QTestEventLoop::instance().enterLoopMSecs(ms: msecs);
62 --loopLevel;
63 }
64
65 static void exitLoop()
66 {
67 if (loopLevel > 0)
68 QTestEventLoop::instance().exitLoop();
69 }
70
71 static bool timeout()
72 {
73 return QTestEventLoop::instance().timeout();
74 }
75
76private slots:
77 void initTestCase();
78
79 void defaultConstruct();
80 void constructByName();
81 void constructByInfo();
82
83 void openExisting_data();
84 void openExisting();
85 void openNotExisting_data();
86 void openNotExisting();
87
88 void baudRate_data();
89 void baudRate();
90 void dataBits_data();
91 void dataBits();
92 void parity_data();
93 void parity();
94 void stopBits_data();
95 void stopBits();
96 void flowControl_data();
97 void flowControl();
98
99 void rts();
100 void dtr();
101 void independenceRtsAndDtr();
102
103 void flush();
104 void doubleFlush();
105
106 void waitForBytesWritten();
107
108 void waitForReadyReadWithTimeout();
109 void waitForReadyReadWithOneByte();
110 void waitForReadyReadWithAlphabet();
111
112 void twoStageSynchronousLoopback();
113
114 void synchronousReadWrite();
115
116 void asynchronousWriteByBytesWritten_data();
117 void asynchronousWriteByBytesWritten();
118
119 void asynchronousWriteByTimer_data();
120 void asynchronousWriteByTimer();
121
122 void asyncReadWithLimitedReadBufferSize();
123
124 void readBufferOverflow();
125 void readAfterInputClear();
126 void synchronousReadWriteAfterAsynchronousReadWrite();
127
128 void controlBreak();
129
130 void clearAfterOpen();
131
132 void readWriteWithDifferentBaudRate_data();
133 void readWriteWithDifferentBaudRate();
134
135protected slots:
136 void handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten);
137 void handleBytesWrittenAndExitLoopSlot2(qint64 bytesWritten);
138
139private:
140 QString m_senderPortName;
141 QString m_receiverPortName;
142 QStringList m_availablePortNames;
143
144 static int loopLevel;
145 static const QByteArray alphabetArray;
146 static const QByteArray newlineArray;
147};
148
149int tst_QSerialPort::loopLevel = 0;
150
151const QByteArray tst_QSerialPort::alphabetArray("ABCDEFGHIJKLMNOPQRSTUVWXUZ");
152const QByteArray tst_QSerialPort::newlineArray("\n\r");
153
154tst_QSerialPort::tst_QSerialPort()
155{
156 qRegisterMetaType<QSerialPort::SerialPortError>(typeName: "QSerialPort::SerialPortError");
157}
158
159void tst_QSerialPort::initTestCase()
160{
161 m_senderPortName = QString::fromLocal8Bit(str: qgetenv(varName: "QTEST_SERIALPORT_SENDER"));
162 m_receiverPortName = QString::fromLocal8Bit(str: qgetenv(varName: "QTEST_SERIALPORT_RECEIVER"));
163 if (m_senderPortName.isEmpty() || m_receiverPortName.isEmpty()) {
164 static const char message[] =
165 "Test doesn't work because the names of serial ports aren't found in env.\n"
166 "Please set environment variables:\n"
167 " QTEST_SERIALPORT_SENDER to name of output serial port\n"
168 " QTEST_SERIALPORT_RECEIVER to name of input serial port\n"
169 "Specify short names of port"
170#if defined(Q_OS_UNIX)
171 ", like: ttyS0\n";
172#elif defined(Q_OS_WIN32)
173 ", like: COM1\n";
174#else
175 "\n";
176#endif
177
178 QSKIP(message);
179 } else {
180 m_availablePortNames << m_senderPortName << m_receiverPortName;
181 }
182}
183
184void tst_QSerialPort::defaultConstruct()
185{
186 QSerialPort serialPort;
187
188 QCOMPARE(serialPort.error(), QSerialPort::NoError);
189 QVERIFY(!serialPort.errorString().isEmpty());
190
191 // properties
192 const qint32 defaultBaudRate = static_cast<qint32>(QSerialPort::Baud9600);
193 QCOMPARE(serialPort.baudRate(), defaultBaudRate);
194 QCOMPARE(serialPort.baudRate(QSerialPort::Input), defaultBaudRate);
195 QCOMPARE(serialPort.baudRate(QSerialPort::Output), defaultBaudRate);
196 QCOMPARE(serialPort.dataBits(), QSerialPort::Data8);
197 QCOMPARE(serialPort.parity(), QSerialPort::NoParity);
198 QCOMPARE(serialPort.stopBits(), QSerialPort::OneStop);
199 QCOMPARE(serialPort.flowControl(), QSerialPort::NoFlowControl);
200
201 QCOMPARE(serialPort.pinoutSignals(), QSerialPort::NoSignal);
202 QCOMPARE(serialPort.isRequestToSend(), false);
203 QCOMPARE(serialPort.isDataTerminalReady(), false);
204
205 // QIODevice
206 QCOMPARE(serialPort.openMode(), QIODevice::NotOpen);
207 QVERIFY(!serialPort.isOpen());
208 QVERIFY(!serialPort.isReadable());
209 QVERIFY(!serialPort.isWritable());
210 QVERIFY(serialPort.isSequential());
211 QCOMPARE(serialPort.canReadLine(), false);
212 QCOMPARE(serialPort.pos(), qlonglong(0));
213 QCOMPARE(serialPort.size(), qlonglong(0));
214 QVERIFY(serialPort.atEnd());
215 QCOMPARE(serialPort.bytesAvailable(), qlonglong(0));
216 QCOMPARE(serialPort.bytesToWrite(), qlonglong(0));
217
218 char c;
219 QCOMPARE(serialPort.read(&c, 1), qlonglong(-1));
220 QCOMPARE(serialPort.write(&c, 1), qlonglong(-1));
221}
222
223void tst_QSerialPort::constructByName()
224{
225 QSerialPort serialPort(m_senderPortName);
226 QCOMPARE(serialPort.portName(), m_senderPortName);
227 serialPort.setPortName(m_receiverPortName);
228 QCOMPARE(serialPort.portName(), m_receiverPortName);
229}
230
231void tst_QSerialPort::constructByInfo()
232{
233 QSerialPortInfo senderPortInfo(m_senderPortName);
234 QSerialPortInfo receiverPortInfo(m_receiverPortName);
235
236#if defined(Q_OS_UNIX)
237 if (senderPortInfo.isNull() || receiverPortInfo.isNull()) {
238 static const char message[] =
239 "Test doesn't work because the specified serial ports aren't"
240 " found in system and can't be constructed by QSerialPortInfo.\n";
241 QSKIP(message);
242 }
243#endif
244
245 QSerialPort serialPort(senderPortInfo);
246 QCOMPARE(serialPort.portName(), m_senderPortName);
247 serialPort.setPort(receiverPortInfo);
248 QCOMPARE(serialPort.portName(), m_receiverPortName);
249}
250
251void tst_QSerialPort::openExisting_data()
252{
253 QTest::addColumn<int>(name: "openMode");
254 QTest::addColumn<bool>(name: "openResult");
255 QTest::addColumn<QSerialPort::SerialPortError>(name: "errorCode");
256
257 QTest::newRow(dataTag: "NotOpen") << int(QIODevice::NotOpen) << false << QSerialPort::UnsupportedOperationError;
258 QTest::newRow(dataTag: "ReadOnly") << int(QIODevice::ReadOnly) << true << QSerialPort::NoError;
259 QTest::newRow(dataTag: "WriteOnly") << int(QIODevice::WriteOnly) << true << QSerialPort::NoError;
260 QTest::newRow(dataTag: "ReadWrite") << int(QIODevice::ReadWrite) << true << QSerialPort::NoError;
261 QTest::newRow(dataTag: "Append") << int(QIODevice::Append) << false << QSerialPort::UnsupportedOperationError;
262 QTest::newRow(dataTag: "Truncate") << int(QIODevice::Truncate) << false << QSerialPort::UnsupportedOperationError;
263 QTest::newRow(dataTag: "Text") << int(QIODevice::Text) << false << QSerialPort::UnsupportedOperationError;
264 QTest::newRow(dataTag: "Unbuffered") << int(QIODevice::Unbuffered) << false << QSerialPort::UnsupportedOperationError;
265}
266
267void tst_QSerialPort::openExisting()
268{
269 QFETCH(int, openMode);
270 QFETCH(bool, openResult);
271 QFETCH(QSerialPort::SerialPortError, errorCode);
272
273 for (const QString &serialPortName : qAsConst(t&: m_availablePortNames)) {
274 QSerialPort serialPort(serialPortName);
275 QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
276 QVERIFY(errorSpy.isValid());
277
278 QCOMPARE(serialPort.portName(), serialPortName);
279 QCOMPARE(serialPort.open(QIODevice::OpenMode(openMode)), openResult);
280 QCOMPARE(serialPort.isOpen(), openResult);
281 QCOMPARE(serialPort.error(), errorCode);
282
283 QCOMPARE(errorSpy.count(), 1);
284 QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), errorCode);
285 }
286}
287
288void tst_QSerialPort::openNotExisting_data()
289{
290 QTest::addColumn<QString>(name: "serialPortName");
291 QTest::addColumn<bool>(name: "openResult");
292 QTest::addColumn<QSerialPort::SerialPortError>(name: "errorCode");
293
294 QTest::newRow(dataTag: "Empty") << QString("") << false << QSerialPort::DeviceNotFoundError;
295 QTest::newRow(dataTag: "Null") << QString() << false << QSerialPort::DeviceNotFoundError;
296 QTest::newRow(dataTag: "NotExists") << QString("ABCDEF") << false << QSerialPort::DeviceNotFoundError;
297}
298
299void tst_QSerialPort::openNotExisting()
300{
301 QFETCH(QString, serialPortName);
302 QFETCH(bool, openResult);
303 //QFETCH(QSerialPort::SerialPortError, errorCode);
304
305 QSerialPort serialPort(serialPortName);
306
307 QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
308 QVERIFY(errorSpy.isValid());
309
310 QCOMPARE(serialPort.portName(), serialPortName);
311 QCOMPARE(serialPort.open(QIODevice::ReadOnly), openResult);
312 QCOMPARE(serialPort.isOpen(), openResult);
313 //QCOMPARE(serialPort.error(), errorCode);
314
315 //QCOMPARE(errorSpy.count(), 1);
316 //QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), errorCode);
317}
318
319void tst_QSerialPort::baudRate_data()
320{
321 QTest::addColumn<qint32>(name: "baudrate");
322 QTest::newRow(dataTag: "Baud1200") << static_cast<qint32>(QSerialPort::Baud1200);
323 QTest::newRow(dataTag: "Baud2400") << static_cast<qint32>(QSerialPort::Baud2400);
324 QTest::newRow(dataTag: "Baud4800") << static_cast<qint32>(QSerialPort::Baud4800);
325 QTest::newRow(dataTag: "Baud9600") << static_cast<qint32>(QSerialPort::Baud9600);
326 QTest::newRow(dataTag: "Baud19200") << static_cast<qint32>(QSerialPort::Baud19200);
327 QTest::newRow(dataTag: "Baud38400") << static_cast<qint32>(QSerialPort::Baud38400);
328 QTest::newRow(dataTag: "Baud57600") << static_cast<qint32>(QSerialPort::Baud57600);
329 QTest::newRow(dataTag: "Baud115200") << static_cast<qint32>(QSerialPort::Baud115200);
330
331 QTest::newRow(dataTag: "31250") << 31250; // custom baudrate (MIDI)
332}
333
334void tst_QSerialPort::baudRate()
335{
336 QFETCH(qint32, baudrate);
337
338 {
339 // setup before opening
340 QSerialPort serialPort(m_senderPortName);
341 QVERIFY(serialPort.setBaudRate(baudrate));
342 QCOMPARE(serialPort.baudRate(), baudrate);
343 QVERIFY(serialPort.open(QIODevice::ReadWrite));
344 }
345
346 {
347 // setup after opening
348 QSerialPort serialPort(m_senderPortName);
349 QVERIFY(serialPort.open(QIODevice::ReadWrite));
350 QVERIFY(serialPort.setBaudRate(baudrate));
351 QCOMPARE(serialPort.baudRate(), baudrate);
352 }
353}
354
355void tst_QSerialPort::dataBits_data()
356{
357 QTest::addColumn<QSerialPort::DataBits>(name: "databits");
358 QTest::newRow(dataTag: "Data5") << QSerialPort::Data5;
359 QTest::newRow(dataTag: "Data6") << QSerialPort::Data6;
360 QTest::newRow(dataTag: "Data7") << QSerialPort::Data7;
361 QTest::newRow(dataTag: "Data8") << QSerialPort::Data8;
362}
363
364void tst_QSerialPort::dataBits()
365{
366 QFETCH(QSerialPort::DataBits, databits);
367
368 {
369 // setup before opening
370 QSerialPort serialPort(m_senderPortName);
371 QVERIFY(serialPort.setDataBits(databits));
372 QCOMPARE(serialPort.dataBits(), databits);
373 QVERIFY(serialPort.open(QIODevice::ReadWrite));
374 }
375
376 {
377 // setup after opening
378 QSerialPort serialPort(m_senderPortName);
379 QVERIFY(serialPort.open(QIODevice::ReadWrite));
380 QVERIFY(serialPort.setDataBits(databits));
381 QCOMPARE(serialPort.dataBits(), databits);
382 }
383}
384
385void tst_QSerialPort::parity_data()
386{
387 QTest::addColumn<QSerialPort::Parity>(name: "parity");
388 QTest::newRow(dataTag: "NoParity") << QSerialPort::NoParity;
389 QTest::newRow(dataTag: "EvenParity") << QSerialPort::EvenParity;
390 QTest::newRow(dataTag: "OddParity") << QSerialPort::OddParity;
391 QTest::newRow(dataTag: "SpaceParity") << QSerialPort::SpaceParity;
392 QTest::newRow(dataTag: "MarkParity") << QSerialPort::MarkParity;
393}
394
395void tst_QSerialPort::parity()
396{
397 QFETCH(QSerialPort::Parity, parity);
398
399 {
400 // setup before opening
401 QSerialPort serialPort(m_senderPortName);
402 QVERIFY(serialPort.setParity(parity));
403 QCOMPARE(serialPort.parity(), parity);
404 QVERIFY(serialPort.open(QIODevice::ReadWrite));
405 }
406
407 {
408 // setup after opening
409 QSerialPort serialPort(m_senderPortName);
410 QVERIFY(serialPort.open(QIODevice::ReadWrite));
411 QVERIFY(serialPort.setParity(parity));
412 QCOMPARE(serialPort.parity(), parity);
413 }
414}
415
416void tst_QSerialPort::stopBits_data()
417{
418 QTest::addColumn<QSerialPort::StopBits>(name: "stopbits");
419 QTest::newRow(dataTag: "OneStop") << QSerialPort::OneStop;
420#ifdef Q_OS_WIN
421 QTest::newRow("OneAndHalfStop") << QSerialPort::OneAndHalfStop;
422#endif
423 QTest::newRow(dataTag: "TwoStop") << QSerialPort::TwoStop;
424}
425
426void tst_QSerialPort::stopBits()
427{
428 QFETCH(QSerialPort::StopBits, stopbits);
429
430 {
431 // setup before opening
432 QSerialPort serialPort(m_senderPortName);
433 QVERIFY(serialPort.setStopBits(stopbits));
434 QCOMPARE(serialPort.stopBits(), stopbits);
435 QVERIFY(serialPort.open(QIODevice::ReadWrite));
436 }
437
438 {
439 // setup after opening
440 QSerialPort serialPort(m_senderPortName);
441 QVERIFY(serialPort.open(QIODevice::ReadWrite));
442 QVERIFY(serialPort.setStopBits(stopbits));
443 QCOMPARE(serialPort.stopBits(), stopbits);
444 }
445}
446
447void tst_QSerialPort::flowControl_data()
448{
449 QTest::addColumn<QSerialPort::FlowControl>(name: "flowcontrol");
450 QTest::newRow(dataTag: "NoFlowControl") << QSerialPort::NoFlowControl;
451 QTest::newRow(dataTag: "HardwareControl") << QSerialPort::HardwareControl;
452 QTest::newRow(dataTag: "SoftwareControl") << QSerialPort::SoftwareControl;
453}
454
455void tst_QSerialPort::flowControl()
456{
457 QFETCH(QSerialPort::FlowControl, flowcontrol);
458
459 {
460 // setup before opening
461 QSerialPort serialPort(m_senderPortName);
462 QVERIFY(serialPort.setFlowControl(flowcontrol));
463 QCOMPARE(serialPort.flowControl(), flowcontrol);
464 QVERIFY(serialPort.open(QIODevice::ReadWrite));
465 }
466
467 {
468 // setup after opening
469 QSerialPort serialPort(m_senderPortName);
470 QVERIFY(serialPort.open(QIODevice::ReadWrite));
471 QVERIFY(serialPort.setFlowControl(flowcontrol));
472 QCOMPARE(serialPort.flowControl(), flowcontrol);
473 }
474}
475
476void tst_QSerialPort::rts()
477{
478 QSerialPort serialPort(m_senderPortName);
479
480 QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
481 QVERIFY(errorSpy.isValid());
482 QSignalSpy rtsSpy(&serialPort, &QSerialPort::requestToSendChanged);
483 QVERIFY(rtsSpy.isValid());
484
485 QVERIFY(serialPort.open(QIODevice::ReadWrite));
486
487 // no flow control
488 QVERIFY(serialPort.setFlowControl(QSerialPort::NoFlowControl));
489 const bool toggle1 = !serialPort.isRequestToSend();
490 QVERIFY(serialPort.setRequestToSend(toggle1));
491 QCOMPARE(serialPort.isRequestToSend(), toggle1);
492
493 // software flow control
494 QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl));
495 const bool toggle2 = !serialPort.isRequestToSend();
496 QVERIFY(serialPort.setRequestToSend(toggle2));
497 QCOMPARE(serialPort.isRequestToSend(), toggle2);
498
499 // hardware flow control
500 QVERIFY(serialPort.setFlowControl(QSerialPort::HardwareControl));
501 const bool toggle3 = !serialPort.isRequestToSend();
502 QVERIFY(!serialPort.setRequestToSend(toggle3)); // not allowed
503 QCOMPARE(serialPort.isRequestToSend(), !toggle3); // same as before
504 QCOMPARE(serialPort.error(), QSerialPort::UnsupportedOperationError);
505
506 QCOMPARE(errorSpy.count(), 2);
507 QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), QSerialPort::NoError);
508 QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(1).at(0)), QSerialPort::UnsupportedOperationError);
509
510 QCOMPARE(rtsSpy.count(), 2);
511 QCOMPARE(qvariant_cast<bool>(rtsSpy.at(0).at(0)), toggle1);
512 QCOMPARE(qvariant_cast<bool>(rtsSpy.at(1).at(0)), toggle2);
513}
514
515void tst_QSerialPort::dtr()
516{
517 QSerialPort serialPort(m_senderPortName);
518
519 QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
520 QVERIFY(errorSpy.isValid());
521 QSignalSpy dtrSpy(&serialPort, &QSerialPort::dataTerminalReadyChanged);
522 QVERIFY(dtrSpy.isValid());
523
524 QVERIFY(serialPort.open(QIODevice::ReadWrite));
525
526 // no flow control
527 QVERIFY(serialPort.setFlowControl(QSerialPort::NoFlowControl));
528 const bool toggle1 = !serialPort.isDataTerminalReady();
529 QVERIFY(serialPort.setDataTerminalReady(toggle1));
530 QCOMPARE(serialPort.isDataTerminalReady(), toggle1);
531
532 // software flow control
533 QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl));
534 const bool toggle2 = !serialPort.isDataTerminalReady();
535 QVERIFY(serialPort.setDataTerminalReady(toggle2));
536 QCOMPARE(serialPort.isDataTerminalReady(), toggle2);
537
538 // hardware flow control
539 QVERIFY(serialPort.setFlowControl(QSerialPort::HardwareControl));
540 const bool toggle3 = !serialPort.isDataTerminalReady();
541 QVERIFY(serialPort.setDataTerminalReady(toggle3));
542 QCOMPARE(serialPort.isDataTerminalReady(), toggle3);
543
544 QCOMPARE(errorSpy.count(), 1);
545 QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), QSerialPort::NoError);
546
547 QCOMPARE(dtrSpy.count(), 3);
548 QCOMPARE(qvariant_cast<bool>(dtrSpy.at(0).at(0)), toggle1);
549 QCOMPARE(qvariant_cast<bool>(dtrSpy.at(1).at(0)), toggle2);
550 QCOMPARE(qvariant_cast<bool>(dtrSpy.at(2).at(0)), toggle3);
551}
552
553void tst_QSerialPort::independenceRtsAndDtr()
554{
555 QSerialPort serialPort(m_senderPortName);
556 QVERIFY(serialPort.open(QIODevice::ReadWrite)); // No flow control by default!
557
558 QVERIFY(serialPort.setDataTerminalReady(true));
559 QVERIFY(serialPort.setRequestToSend(true));
560 QVERIFY(serialPort.isDataTerminalReady());
561 QVERIFY(serialPort.isRequestToSend());
562
563 // check that DTR changing does not change RTS
564 QVERIFY(serialPort.setDataTerminalReady(false));
565 QVERIFY(!serialPort.isDataTerminalReady());
566 QVERIFY(serialPort.isRequestToSend());
567 QVERIFY(serialPort.setDataTerminalReady(true));
568 QVERIFY(serialPort.isDataTerminalReady());
569 QVERIFY(serialPort.isRequestToSend());
570
571 // check that RTS changing does not change DTR
572 QVERIFY(serialPort.setRequestToSend(false));
573 QVERIFY(!serialPort.isRequestToSend());
574 QVERIFY(serialPort.isDataTerminalReady());
575 QVERIFY(serialPort.setRequestToSend(true));
576 QVERIFY(serialPort.isRequestToSend());
577 QVERIFY(serialPort.isDataTerminalReady());
578
579 // check that baud rate changing does not change DTR or RTS
580 QVERIFY(serialPort.setBaudRate(115200));
581 QVERIFY(serialPort.isRequestToSend());
582 QVERIFY(serialPort.isDataTerminalReady());
583
584 // check that data bits changing does not change DTR or RTS
585 QVERIFY(serialPort.setDataBits(QSerialPort::Data7));
586 QVERIFY(serialPort.isRequestToSend());
587 QVERIFY(serialPort.isDataTerminalReady());
588
589 // check that parity changing does not change DTR or RTS
590 QVERIFY(serialPort.setParity(QSerialPort::EvenParity));
591 QVERIFY(serialPort.isRequestToSend());
592 QVERIFY(serialPort.isDataTerminalReady());
593
594 // check that stop bits changing does not change DTR or RTS
595 QVERIFY(serialPort.setStopBits(QSerialPort::TwoStop));
596 QVERIFY(serialPort.isRequestToSend());
597 QVERIFY(serialPort.isDataTerminalReady());
598
599 // check that software flow control changing does not change DTR or RTS
600 QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl));
601 QVERIFY(serialPort.isRequestToSend());
602 QVERIFY(serialPort.isDataTerminalReady());
603}
604
605void tst_QSerialPort::handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten)
606{
607 QCOMPARE(bytesWritten, qint64(alphabetArray.size() + newlineArray.size()));
608 exitLoop();
609}
610
611void tst_QSerialPort::flush()
612{
613#ifdef Q_OS_WIN
614 QSKIP("flush() does not work on Windows");
615#endif
616
617 // the dummy device on other side also has to be open
618 QSerialPort dummySerialPort(m_receiverPortName);
619 QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));
620
621 QSerialPort serialPort(m_senderPortName);
622 connect(sender: &serialPort, signal: &QSerialPort::bytesWritten, receiver: this, slot: &tst_QSerialPort::handleBytesWrittenAndExitLoopSlot);
623 QSignalSpy bytesWrittenSpy(&serialPort, &QSerialPort::bytesWritten);
624
625 QVERIFY(serialPort.open(QIODevice::WriteOnly));
626 serialPort.write(data: alphabetArray + newlineArray);
627 QCOMPARE(serialPort.bytesToWrite(), qint64(alphabetArray.size() + newlineArray.size()));
628 serialPort.flush();
629 QCOMPARE(serialPort.bytesToWrite(), qint64(0));
630 enterLoop(secs: 1);
631 QVERIFY2(!timeout(), "Timed out when waiting for the bytesWritten(qint64) signal.");
632 QCOMPARE(bytesWrittenSpy.count(), 1);
633}
634
635void tst_QSerialPort::handleBytesWrittenAndExitLoopSlot2(qint64 bytesWritten)
636{
637 static qint64 bytes = 0;
638 bytes += bytesWritten;
639
640 QVERIFY(bytesWritten == newlineArray.size() || bytesWritten == alphabetArray.size());
641
642 if (bytes == (alphabetArray.size() + newlineArray.size()))
643 exitLoop();
644}
645
646void tst_QSerialPort::doubleFlush()
647{
648#ifdef Q_OS_WIN
649 QSKIP("flush() does not work on Windows");
650#endif
651
652 // the dummy device on other side also has to be open
653 QSerialPort dummySerialPort(m_receiverPortName);
654 QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));
655
656 QSerialPort serialPort(m_senderPortName);
657 connect(sender: &serialPort, signal: &QSerialPort::bytesWritten, receiver: this, slot: &tst_QSerialPort::handleBytesWrittenAndExitLoopSlot2);
658 QSignalSpy bytesWrittenSpy(&serialPort, &QSerialPort::bytesWritten);
659
660 QVERIFY(serialPort.open(QIODevice::WriteOnly));
661 serialPort.write(data: alphabetArray);
662 QCOMPARE(serialPort.bytesToWrite(), qint64(alphabetArray.size()));
663 serialPort.flush();
664 QCOMPARE(serialPort.bytesToWrite(), qint64(0));
665 serialPort.write(data: newlineArray);
666 QCOMPARE(serialPort.bytesToWrite(), qint64(newlineArray.size()));
667 serialPort.flush();
668 QCOMPARE(serialPort.bytesToWrite(), qint64(0));
669
670 enterLoop(secs: 1);
671 QVERIFY2(!timeout(), "Timed out when waiting for the bytesWritten(qint64) signal.");
672 QCOMPARE(bytesWrittenSpy.count(), 2);
673}
674
675void tst_QSerialPort::waitForBytesWritten()
676{
677 // the dummy device on other side also has to be open
678 QSerialPort dummySerialPort(m_receiverPortName);
679 QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));
680
681 QSerialPort serialPort(m_senderPortName);
682 QVERIFY(serialPort.open(QIODevice::WriteOnly));
683 serialPort.write(data: alphabetArray);
684 const qint64 toWrite = serialPort.bytesToWrite();
685 QVERIFY(serialPort.waitForBytesWritten(1000));
686 QVERIFY(toWrite > serialPort.bytesToWrite());
687}
688
689void tst_QSerialPort::waitForReadyReadWithTimeout()
690{
691 // the dummy device on other side also has to be open
692 QSerialPort dummySerialPort(m_senderPortName);
693 QVERIFY(dummySerialPort.open(QIODevice::WriteOnly));
694
695 QSerialPort receiverSerialPort(m_receiverPortName);
696 QVERIFY(receiverSerialPort.open(QIODevice::ReadOnly));
697 QVERIFY(!receiverSerialPort.waitForReadyRead(5));
698 QCOMPARE(receiverSerialPort.bytesAvailable(), qint64(0));
699 QCOMPARE(receiverSerialPort.error(), QSerialPort::TimeoutError);
700}
701
702void tst_QSerialPort::waitForReadyReadWithOneByte()
703{
704 const qint64 oneByte = 1;
705 const int waitMsecs = 50;
706
707 QSerialPort senderSerialPort(m_senderPortName);
708 QVERIFY(senderSerialPort.open(QIODevice::WriteOnly));
709 QSerialPort receiverSerialPort(m_receiverPortName);
710 QSignalSpy readyReadSpy(&receiverSerialPort, &QSerialPort::readyRead);
711 QVERIFY(readyReadSpy.isValid());
712 QVERIFY(receiverSerialPort.open(QIODevice::ReadOnly));
713 QCOMPARE(senderSerialPort.write(alphabetArray.constData(), oneByte), oneByte);
714 QVERIFY(senderSerialPort.waitForBytesWritten(waitMsecs));
715 QVERIFY(receiverSerialPort.waitForReadyRead(waitMsecs));
716 QCOMPARE(receiverSerialPort.bytesAvailable(), oneByte);
717 QCOMPARE(receiverSerialPort.error(), QSerialPort::NoError);
718 QCOMPARE(readyReadSpy.count(), 1);
719}
720
721void tst_QSerialPort::waitForReadyReadWithAlphabet()
722{
723 const int waitMsecs = 50;
724
725 QSerialPort senderSerialPort(m_senderPortName);
726 QVERIFY(senderSerialPort.open(QIODevice::WriteOnly));
727 QSerialPort receiverSerialPort(m_receiverPortName);
728 QSignalSpy readyReadSpy(&receiverSerialPort, &QSerialPort::readyRead);
729 QVERIFY(readyReadSpy.isValid());
730 QVERIFY(receiverSerialPort.open(QIODevice::ReadOnly));
731 QCOMPARE(senderSerialPort.write(alphabetArray), qint64(alphabetArray.size()));
732 QVERIFY(senderSerialPort.waitForBytesWritten(waitMsecs));
733
734 do {
735 QVERIFY(receiverSerialPort.waitForReadyRead(waitMsecs));
736 } while (receiverSerialPort.bytesAvailable() < qint64(alphabetArray.size()));
737
738 QCOMPARE(receiverSerialPort.error(), QSerialPort::NoError);
739 QVERIFY(readyReadSpy.count() > 0);
740}
741
742void tst_QSerialPort::twoStageSynchronousLoopback()
743{
744 QSerialPort senderPort(m_senderPortName);
745 QVERIFY(senderPort.open(QSerialPort::ReadWrite));
746
747 QSerialPort receiverPort(m_receiverPortName);
748 QVERIFY(receiverPort.open(QSerialPort::ReadWrite));
749
750 const int waitMsecs = 50;
751
752 // first stage
753 senderPort.write(data: newlineArray);
754 senderPort.waitForBytesWritten(msecs: waitMsecs);
755 QTest::qSleep(ms: waitMsecs);
756 receiverPort.waitForReadyRead(msecs: waitMsecs);
757 QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
758
759 receiverPort.write(data: receiverPort.readAll());
760 receiverPort.waitForBytesWritten(msecs: waitMsecs);
761 QTest::qSleep(ms: waitMsecs);
762 senderPort.waitForReadyRead(msecs: waitMsecs);
763 QCOMPARE(senderPort.bytesAvailable(), qint64(newlineArray.size()));
764 QCOMPARE(senderPort.readAll(), newlineArray);
765
766 // second stage
767 senderPort.write(data: newlineArray);
768 senderPort.waitForBytesWritten(msecs: waitMsecs);
769 QTest::qSleep(ms: waitMsecs);
770 receiverPort.waitForReadyRead(msecs: waitMsecs);
771 QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
772 receiverPort.write(data: receiverPort.readAll());
773 receiverPort.waitForBytesWritten(msecs: waitMsecs);
774 QTest::qSleep(ms: waitMsecs);
775 senderPort.waitForReadyRead(msecs: waitMsecs);
776 QCOMPARE(senderPort.bytesAvailable(), qint64(newlineArray.size()));
777 QCOMPARE(senderPort.readAll(), newlineArray);
778}
779
780void tst_QSerialPort::synchronousReadWrite()
781{
782 QSerialPort senderPort(m_senderPortName);
783 QVERIFY(senderPort.open(QSerialPort::WriteOnly));
784
785 QSerialPort receiverPort(m_receiverPortName);
786 QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
787
788 QByteArray writeData;
789 for (int i = 0; i < 1024; ++i)
790 writeData.append(c: static_cast<char>(i));
791
792 senderPort.write(data: writeData);
793 senderPort.waitForBytesWritten(msecs: -1);
794
795 QByteArray readData;
796 while ((readData.size() < writeData.size()) && receiverPort.waitForReadyRead(msecs: 100))
797 readData.append(a: receiverPort.readAll());
798
799 QCOMPARE(readData, writeData);
800}
801
802class AsyncReader : public QObject
803{
804 Q_OBJECT
805public:
806 explicit AsyncReader(QSerialPort &port, Qt::ConnectionType connectionType, int expectedBytesCount)
807 : serialPort(port), expectedBytesCount(expectedBytesCount)
808 {
809 connect(sender: &serialPort, signal: &QSerialPort::readyRead, receiver: this, slot: &AsyncReader::receive, type: connectionType);
810 }
811
812private slots:
813 void receive()
814 {
815 if (serialPort.bytesAvailable() < expectedBytesCount)
816 return;
817 tst_QSerialPort::exitLoop();
818 }
819
820private:
821 QSerialPort &serialPort;
822 const int expectedBytesCount;
823};
824
825class AsyncWriterByBytesWritten : public QObject
826{
827 Q_OBJECT
828public:
829 explicit AsyncWriterByBytesWritten(
830 QSerialPort &port, Qt::ConnectionType connectionType, const QByteArray &dataToWrite)
831 : serialPort(port), writeChunkSize(0)
832 {
833 writeBuffer.setData(dataToWrite);
834 writeBuffer.open(openMode: QIODevice::ReadOnly);
835 connect(sender: &serialPort, signal: &QSerialPort::bytesWritten, receiver: this, slot: &AsyncWriterByBytesWritten::send, type: connectionType);
836 send();
837 }
838
839private slots:
840 void send()
841 {
842 if (writeBuffer.bytesAvailable() > 0)
843 serialPort.write(data: writeBuffer.read(maxlen: ++writeChunkSize));
844 }
845
846private:
847 QSerialPort &serialPort;
848 QBuffer writeBuffer;
849 int writeChunkSize;
850};
851
852void tst_QSerialPort::asynchronousWriteByBytesWritten_data()
853{
854 QTest::addColumn<Qt::ConnectionType>(name: "readConnectionType");
855 QTest::addColumn<Qt::ConnectionType>(name: "writeConnectionType");
856
857 QTest::newRow(dataTag: "BothQueued") << Qt::QueuedConnection << Qt::QueuedConnection;
858 QTest::newRow(dataTag: "BothDirect") << Qt::DirectConnection << Qt::DirectConnection;
859 QTest::newRow(dataTag: "ReadDirectWriteQueued") << Qt::DirectConnection << Qt::QueuedConnection;
860 QTest::newRow(dataTag: "ReadQueuedWriteDirect") << Qt::QueuedConnection << Qt::DirectConnection;
861}
862
863void tst_QSerialPort::asynchronousWriteByBytesWritten()
864{
865 QFETCH(Qt::ConnectionType, readConnectionType);
866 QFETCH(Qt::ConnectionType, writeConnectionType);
867
868 QSerialPort receiverPort(m_receiverPortName);
869 QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
870 AsyncReader reader(receiverPort, readConnectionType, alphabetArray.size());
871
872 QSerialPort senderPort(m_senderPortName);
873 QVERIFY(senderPort.open(QSerialPort::WriteOnly));
874 AsyncWriterByBytesWritten writer(senderPort, writeConnectionType, alphabetArray);
875
876 enterLoop(secs: 1);
877 QVERIFY2(!timeout(), "Timed out when waiting for the read or write.");
878 QCOMPARE(receiverPort.bytesAvailable(), qint64(alphabetArray.size()));
879 QCOMPARE(receiverPort.readAll(), alphabetArray);
880}
881
882class AsyncWriterByTimer : public QObject
883{
884 Q_OBJECT
885public:
886 explicit AsyncWriterByTimer(
887 QSerialPort &port, Qt::ConnectionType connectionType, const QByteArray &dataToWrite)
888 : serialPort(port), writeChunkSize(0)
889 {
890 writeBuffer.setData(dataToWrite);
891 writeBuffer.open(openMode: QIODevice::ReadOnly);
892 connect(sender: &timer, signal: &QTimer::timeout, receiver: this, slot: &AsyncWriterByTimer::send, type: connectionType);
893 timer.start(msec: 0);
894 }
895
896private slots:
897 void send()
898 {
899 if (writeBuffer.bytesAvailable() > 0)
900 serialPort.write(data: writeBuffer.read(maxlen: ++writeChunkSize));
901 else
902 timer.stop();
903 }
904
905private:
906 QSerialPort &serialPort;
907 QBuffer writeBuffer;
908 int writeChunkSize;
909 QTimer timer;
910};
911
912void tst_QSerialPort::asynchronousWriteByTimer_data()
913{
914 QTest::addColumn<Qt::ConnectionType>(name: "readConnectionType");
915 QTest::addColumn<Qt::ConnectionType>(name: "writeConnectionType");
916
917 QTest::newRow(dataTag: "BothQueued") << Qt::QueuedConnection << Qt::QueuedConnection;
918 QTest::newRow(dataTag: "BothDirect") << Qt::DirectConnection << Qt::DirectConnection;
919 QTest::newRow(dataTag: "ReadDirectWriteQueued") << Qt::DirectConnection << Qt::QueuedConnection;
920 QTest::newRow(dataTag: "ReadQueuedWriteDirect") << Qt::QueuedConnection << Qt::DirectConnection;
921}
922
923void tst_QSerialPort::asynchronousWriteByTimer()
924{
925 QFETCH(Qt::ConnectionType, readConnectionType);
926 QFETCH(Qt::ConnectionType, writeConnectionType);
927
928 QSerialPort receiverPort(m_receiverPortName);
929 QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
930 AsyncReader reader(receiverPort, readConnectionType, alphabetArray.size());
931
932 QSerialPort senderPort(m_senderPortName);
933 QVERIFY(senderPort.open(QSerialPort::WriteOnly));
934 AsyncWriterByTimer writer(senderPort, writeConnectionType, alphabetArray);
935
936 enterLoop(secs: 1);
937 QVERIFY2(!timeout(), "Timed out when waiting for the read or write.");
938 QCOMPARE(receiverPort.bytesAvailable(), qint64(alphabetArray.size()));
939 QCOMPARE(receiverPort.readAll(), alphabetArray);
940}
941
942class AsyncReader2 : public QObject
943{
944 Q_OBJECT
945public:
946 explicit AsyncReader2(QSerialPort &port, const QByteArray &expectedData)
947 : serialPort(port), expectedData(expectedData)
948 {
949 connect(sender: &serialPort, signal: &QSerialPort::readyRead, receiver: this, slot: &AsyncReader2::receive);
950 }
951
952private slots:
953 void receive()
954 {
955 receivedData.append(a: serialPort.readAll());
956 if (receivedData == expectedData)
957 tst_QSerialPort::exitLoop();
958 }
959
960private:
961 QSerialPort &serialPort;
962 const QByteArray expectedData;
963 QByteArray receivedData;
964};
965
966void tst_QSerialPort::asyncReadWithLimitedReadBufferSize()
967{
968 QSerialPort senderPort(m_senderPortName);
969 QVERIFY(senderPort.open(QSerialPort::WriteOnly));
970
971 QSerialPort receiverPort(m_receiverPortName);
972 QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
973
974 receiverPort.setReadBufferSize(1);
975 QCOMPARE(receiverPort.readBufferSize(), qint64(1));
976
977 AsyncReader2 reader(receiverPort, alphabetArray);
978
979 QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));
980
981 enterLoop(secs: 1);
982 QVERIFY2(!timeout(), "Timed out when waiting for the read or write.");
983}
984
985void tst_QSerialPort::readBufferOverflow()
986{
987 QSerialPort senderPort(m_senderPortName);
988 QVERIFY(senderPort.open(QSerialPort::WriteOnly));
989
990 QSerialPort receiverPort(m_receiverPortName);
991 QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
992
993 const int readBufferSize = alphabetArray.size() / 2;
994 receiverPort.setReadBufferSize(readBufferSize);
995 QCOMPARE(receiverPort.readBufferSize(), qint64(readBufferSize));
996
997 QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));
998 QVERIFY2(senderPort.waitForBytesWritten(100), "Waiting for bytes written failed");
999
1000 QByteArray readData;
1001 while (receiverPort.waitForReadyRead(msecs: 100)) {
1002 QVERIFY(receiverPort.bytesAvailable() > 0);
1003 readData += receiverPort.readAll();
1004 }
1005
1006 QCOMPARE(readData, alphabetArray);
1007
1008 // No more bytes available
1009 QVERIFY(receiverPort.bytesAvailable() == 0);
1010}
1011
1012void tst_QSerialPort::readAfterInputClear()
1013{
1014 QSerialPort senderPort(m_senderPortName);
1015 QVERIFY(senderPort.open(QSerialPort::WriteOnly));
1016
1017 QSerialPort receiverPort(m_receiverPortName);
1018 QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
1019
1020 const int readBufferSize = alphabetArray.size() / 2;
1021 receiverPort.setReadBufferSize(readBufferSize);
1022 QCOMPARE(receiverPort.readBufferSize(), qint64(readBufferSize));
1023
1024 const int waitMsecs = 100;
1025
1026 // First write more than read buffer size
1027 QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));
1028 QVERIFY2(senderPort.waitForBytesWritten(waitMsecs), "Waiting for bytes written failed");
1029
1030 // Wait for first part of data into read buffer
1031 while (receiverPort.waitForReadyRead(msecs: waitMsecs));
1032 QCOMPARE(receiverPort.bytesAvailable(), qint64(readBufferSize));
1033 // Wait for second part of data into driver's FIFO
1034 QTest::qSleep(ms: waitMsecs);
1035
1036 QVERIFY(receiverPort.clear(QSerialPort::Input));
1037 QCOMPARE(receiverPort.bytesAvailable(), qint64(0));
1038
1039 // Second write less than read buffer size
1040 QCOMPARE(senderPort.write(newlineArray), qint64(newlineArray.size()));
1041 QVERIFY2(senderPort.waitForBytesWritten(waitMsecs), "Waiting for bytes written failed");
1042
1043 while (receiverPort.waitForReadyRead(msecs: waitMsecs));
1044 QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
1045 QCOMPARE(receiverPort.readAll(), newlineArray);
1046
1047 // No more bytes available
1048 QVERIFY(receiverPort.bytesAvailable() == 0);
1049}
1050
1051class MasterTransactor : public QObject
1052{
1053 Q_OBJECT
1054public:
1055 explicit MasterTransactor(const QString &name)
1056 : serialPort(name)
1057 {
1058 }
1059
1060public slots:
1061 void open()
1062 {
1063 if (serialPort.open(mode: QSerialPort::ReadWrite)) {
1064 createAsynchronousConnection();
1065 serialPort.write(data: "A", len: 1);
1066 }
1067 }
1068
1069private slots:
1070 void synchronousTransaction()
1071 {
1072 serialPort.write(data: "B", len: 1);
1073 if (serialPort.waitForBytesWritten(msecs: 100)) {
1074 if (serialPort.waitForReadyRead(msecs: 100))
1075 tst_QSerialPort::exitLoop();
1076 }
1077 }
1078
1079 void transaction()
1080 {
1081 deleteAsyncronousConnection();
1082 synchronousTransaction();
1083 }
1084
1085private:
1086 void createAsynchronousConnection()
1087 {
1088 connect(sender: &serialPort, signal: &QSerialPort::readyRead, receiver: this, slot: &MasterTransactor::transaction);
1089 }
1090
1091 void deleteAsyncronousConnection()
1092 {
1093 serialPort.disconnect();
1094 }
1095
1096 QSerialPort serialPort;
1097};
1098
1099class SlaveTransactor : public QObject
1100{
1101 Q_OBJECT
1102public:
1103 explicit SlaveTransactor(const QString &name)
1104 : serialPort(new QSerialPort(name, this))
1105 {
1106 connect(sender: serialPort, signal: &QSerialPort::readyRead, receiver: this, slot: &SlaveTransactor::transaction);
1107 }
1108
1109public slots:
1110 void open()
1111 {
1112 if (serialPort->open(mode: QSerialPort::ReadWrite))
1113 emit ready();
1114 }
1115
1116signals:
1117 void ready();
1118
1119private slots:
1120 void transaction()
1121 {
1122 serialPort->write(data: "Z", len: 1);
1123 }
1124
1125private:
1126 QSerialPort *serialPort;
1127};
1128
1129void tst_QSerialPort::synchronousReadWriteAfterAsynchronousReadWrite()
1130{
1131 MasterTransactor master(m_senderPortName);
1132 auto slave = new SlaveTransactor(m_receiverPortName);
1133
1134 QThread thread;
1135 slave->moveToThread(thread: &thread);
1136 thread.start();
1137
1138 QObject::connect(sender: &thread, signal: &QThread::finished, receiver: slave, slot: &SlaveTransactor::deleteLater);
1139 QObject::connect(sender: slave, signal: &SlaveTransactor::ready, receiver: &master, slot: &MasterTransactor::open);
1140
1141 QMetaObject::invokeMethod(obj: slave, member: "open", type: Qt::QueuedConnection);
1142
1143 tst_QSerialPort::enterLoopMsecs(msecs: 2000);
1144
1145 thread.quit();
1146 thread.wait();
1147
1148 QVERIFY2(!timeout(), "Timed out when testing of transactions.");
1149}
1150
1151class BreakReader : public QObject
1152{
1153 Q_OBJECT
1154public:
1155 explicit BreakReader(QSerialPort &port)
1156 : serialPort(port)
1157 {
1158 connect(sender: &serialPort, signal: &QSerialPort::readyRead, receiver: this, slot: &BreakReader::receive);
1159 }
1160
1161private slots:
1162 void receive()
1163 {
1164 tst_QSerialPort::exitLoop();
1165 }
1166
1167private:
1168 QSerialPort &serialPort;
1169};
1170
1171void tst_QSerialPort::controlBreak()
1172{
1173 QSerialPort senderPort(m_senderPortName);
1174 QVERIFY(senderPort.open(QSerialPort::WriteOnly));
1175 QCOMPARE(senderPort.isBreakEnabled(), false);
1176
1177 QSignalSpy breakSpy(&senderPort, &QSerialPort::breakEnabledChanged);
1178 QVERIFY(breakSpy.isValid());
1179
1180 QSerialPort receiverPort(m_receiverPortName);
1181 QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
1182
1183 BreakReader reader(receiverPort);
1184
1185 QVERIFY(senderPort.setBreakEnabled(true));
1186 QCOMPARE(senderPort.isBreakEnabled(), true);
1187
1188 enterLoop(secs: 1);
1189 QVERIFY2(!timeout(), "Timed out when waiting for the read of break state.");
1190 QVERIFY(receiverPort.bytesAvailable() > 0);
1191
1192 const QByteArray actual = receiverPort.readAll();
1193 const QByteArray expected(actual.size(), '\0');
1194 QCOMPARE(actual, expected);
1195
1196 QVERIFY(senderPort.setBreakEnabled(false));
1197 QCOMPARE(senderPort.isBreakEnabled(), false);
1198
1199 QCOMPARE(breakSpy.count(), 2);
1200 QCOMPARE(qvariant_cast<bool>(breakSpy.at(0).at(0)), true);
1201 QCOMPARE(qvariant_cast<bool>(breakSpy.at(1).at(0)), false);
1202}
1203
1204void tst_QSerialPort::clearAfterOpen()
1205{
1206 QSerialPort senderPort(m_senderPortName);
1207 QVERIFY(senderPort.open(QSerialPort::ReadWrite));
1208 QCOMPARE(senderPort.error(), QSerialPort::NoError);
1209 QVERIFY(senderPort.clear());
1210 QCOMPARE(senderPort.error(), QSerialPort::NoError);
1211}
1212
1213void tst_QSerialPort::readWriteWithDifferentBaudRate_data()
1214{
1215 QTest::addColumn<int>(name: "senderBaudRate");
1216 QTest::addColumn<int>(name: "receiverBaudRate");
1217 QTest::addColumn<bool>(name: "expectedResult");
1218
1219 QTest::newRow(dataTag: "9600, 9600") << 9600 << 9600 << true;
1220 QTest::newRow(dataTag: "115200, 115200") << 115200 << 115200 << true;
1221 QTest::newRow(dataTag: "9600, 115200") << 9600 << 115200 << false;
1222
1223 QTest::newRow(dataTag: "31250, 31250") << 31250 << 31250 << true; // custom baudrate (MIDI)
1224 QTest::newRow(dataTag: "31250, 115200") << 31250 << 115200 << false;
1225
1226#ifdef Q_OS_LINUX
1227 QTest::newRow(dataTag: "14400, 14400") << 14400 << 14400 << true; // custom baudrate for Linux
1228 QTest::newRow(dataTag: "14400, 115200") << 14400 << 115200 << false;
1229#endif
1230}
1231
1232void tst_QSerialPort::readWriteWithDifferentBaudRate()
1233{
1234 QFETCH(int, senderBaudRate);
1235 QFETCH(int, receiverBaudRate);
1236 QFETCH(bool, expectedResult);
1237
1238 {
1239 // setup before opening
1240 QSerialPort senderSerialPort(m_senderPortName);
1241 QVERIFY(senderSerialPort.setBaudRate(senderBaudRate));
1242 QCOMPARE(senderSerialPort.baudRate(), senderBaudRate);
1243 QVERIFY(senderSerialPort.open(QSerialPort::ReadWrite));
1244 QSerialPort receiverSerialPort(m_receiverPortName);
1245 QVERIFY(receiverSerialPort.setBaudRate(receiverBaudRate));
1246 QCOMPARE(receiverSerialPort.baudRate(), receiverBaudRate);
1247 QVERIFY(receiverSerialPort.open(QSerialPort::ReadWrite));
1248
1249 QCOMPARE(senderSerialPort.write(alphabetArray), qint64(alphabetArray.size()));
1250 QVERIFY(senderSerialPort.waitForBytesWritten(500));
1251
1252 do {
1253 QVERIFY(receiverSerialPort.waitForReadyRead(500));
1254 } while (receiverSerialPort.bytesAvailable() < alphabetArray.size());
1255
1256 if (expectedResult)
1257 QVERIFY(receiverSerialPort.readAll() == alphabetArray);
1258 else
1259 QVERIFY(receiverSerialPort.readAll() != alphabetArray);
1260 }
1261
1262 {
1263 // setup after opening
1264 QSerialPort senderSerialPort(m_senderPortName);
1265 QVERIFY(senderSerialPort.open(QSerialPort::ReadWrite));
1266 QVERIFY(senderSerialPort.setBaudRate(senderBaudRate));
1267 QCOMPARE(senderSerialPort.baudRate(), senderBaudRate);
1268 QSerialPort receiverSerialPort(m_receiverPortName);
1269 QVERIFY(receiverSerialPort.open(QSerialPort::ReadWrite));
1270 QVERIFY(receiverSerialPort.setBaudRate(receiverBaudRate));
1271 QCOMPARE(receiverSerialPort.baudRate(), receiverBaudRate);
1272
1273 QCOMPARE(senderSerialPort.write(alphabetArray), qint64(alphabetArray.size()));
1274 QVERIFY(senderSerialPort.waitForBytesWritten(500));
1275
1276 do {
1277 QVERIFY(receiverSerialPort.waitForReadyRead(500));
1278 } while (receiverSerialPort.bytesAvailable() < alphabetArray.size());
1279
1280 if (expectedResult)
1281 QVERIFY(receiverSerialPort.readAll() == alphabetArray);
1282 else
1283 QVERIFY(receiverSerialPort.readAll() != alphabetArray);
1284 }
1285}
1286
1287QTEST_MAIN(tst_QSerialPort)
1288#include "tst_qserialport.moc"
1289

source code of qtserialport/tests/auto/qserialport/tst_qserialport.cpp