fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / kpty / tests / kptyprocesstest.cpp
blobe5aea6856d1ef596d4c72a0a9c0e5bc716c7ddc7
1 /*
2 This file is part of the KDE libraries
4 Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
22 #include "kptyprocesstest.h"
24 #include <kptydevice.h>
25 #include <qtest_kde.h>
27 void KPtyProcessTest::test_suspend_pty()
29 KPtyProcess p;
30 p.setPtyChannels(KPtyProcess::AllChannels);
31 p.setProgram("ping", QStringList() << "-i" << "0.5" << "localhost");
32 p.start();
34 // verify that data is available to read from the pty
35 QVERIFY(p.pty()->waitForReadyRead(1500));
37 // suspend the pty device and read all available data from it
38 p.pty()->setSuspended(true);
39 QVERIFY(p.pty()->isSuspended());
40 p.pty()->readAll();
42 // verify that no data was read by the pty
43 QVERIFY(!p.pty()->waitForReadyRead(1500));
45 // allow process to write more data
46 p.pty()->setSuspended(false);
47 QVERIFY(!p.pty()->isSuspended());
49 // verify that data is available once more
50 QVERIFY(p.pty()->waitForReadyRead(1500));
51 p.pty()->readAll();
53 p.terminate();
54 p.waitForFinished();
57 void KPtyProcessTest::test_shared_pty()
59 // start a first process
60 KPtyProcess p;
61 p.setProgram("cat");
62 p.setPtyChannels(KPtyProcess::AllChannels);
63 p.pty()->setEcho(false);
64 p.start();
66 // start a second process using the first one's fd
67 int fd = p.pty()->masterFd();
69 KPtyProcess p2(fd);
70 p2.setProgram("echo", QStringList() << "hello from me");
71 p2.setPtyChannels(KPtyProcess::AllChannels);
72 p2.pty()->setEcho(false);
73 p2.start();
75 // read the second processes greeting from the first process' pty
76 QVERIFY(p.pty()->waitForReadyRead(1000));
77 QCOMPARE(p.pty()->readAll(), QByteArray("hello from me\r\n"));
79 // write to the second process' pty
80 p2.pty()->write("hello from process 2\n");
81 QVERIFY(p2.pty()->waitForBytesWritten(1000));
83 // read the result back from the first process' pty
84 QVERIFY(p.pty()->waitForReadyRead(1000));
85 QCOMPARE(p.pty()->readAll(), QByteArray("hello from process 2\r\n"));
87 // write to the first process' pty
88 p.pty()->write("hi from process 1\n");
89 QVERIFY(p.pty()->waitForBytesWritten(1000));
91 // read the result back from the second process' pty
92 QVERIFY(p2.pty()->waitForReadyRead(1000));
93 QCOMPARE(p2.pty()->readAll(), QByteArray("hi from process 1\r\n"));
95 // cleanup
96 p.terminate();
97 p2.terminate();
98 p.waitForFinished(1000);
99 p2.waitForFinished(1000);
102 void KPtyProcessTest::test_pty_basic()
104 KPtyProcess p;
105 p.setProgram("/bin/bash", QStringList() << "-c" << "read -s VAL; echo \"1: $VAL\"; echo \"2: $VAL\" >&2");
106 p.setPtyChannels(KPtyProcess::AllChannels);
107 p.pty()->setEcho(false);
108 p.start();
109 p.pty()->write("test\n");
110 p.pty()->waitForBytesWritten(1000);
111 p.waitForFinished(1000);
112 p.pty()->waitForReadyRead(1000);
113 QString output = p.pty()->readAll();
114 QCOMPARE(output, QLatin1String("1: test\r\n2: test\r\n"));
118 void KPtyProcessTest::slotReadyRead()
120 delay.start(30);
123 void KPtyProcessTest::slotDoRead()
125 while (sp.pty()->canReadLine())
126 log.append('>').append(sp.pty()->readLine()).append("$\n");
127 log.append("!\n");
130 void KPtyProcessTest::slotReadEof()
132 log.append('|').append(sp.pty()->readAll()).append("$\n");
135 void KPtyProcessTest::slotBytesWritten()
137 log.append('<');
140 static const char * const feeds[] = {
141 "bla\n",
142 "foo\x04", "bar\n",
143 "fooish\nbar\n",
144 "\x04",
148 static const char want[] =
149 "<>bla\r\n$\n!\n"
150 "<!\n<>foobar\r\n$\n!\n"
151 "<>fooish\r\n$\n>bar\r\n$\n!\n"
152 "<|$\n"
155 void KPtyProcessTest::slotStep()
157 if (feeds[phase]) {
158 sp.pty()->write(feeds[phase]);
159 phase++;
163 void KPtyProcessTest::test_pty_signals()
165 sp.setShellCommand("cat; sleep .1");
166 sp.setPtyChannels(KPtyProcess::StdinChannel | KPtyProcess::StdoutChannel);
167 sp.pty()->setEcho(false);
168 connect(sp.pty(), SIGNAL(readyRead()), SLOT(slotReadyRead()));
169 connect(sp.pty(), SIGNAL(readEof()), SLOT(slotReadEof()));
170 connect(sp.pty(), SIGNAL(bytesWritten(qint64)), SLOT(slotBytesWritten()));
171 QTimer t;
172 connect(&t, SIGNAL(timeout()), SLOT(slotStep()));
173 t.start(50);
174 connect(&delay, SIGNAL(timeout()), SLOT(slotDoRead()));
175 delay.setSingleShot(true);
176 sp.start();
177 sp.pty()->closeSlave();
178 phase = 0;
179 QTest::kWaitForSignal(&sp, SIGNAL(finished(int, QProcess::ExitStatus)), 1000);
180 QCOMPARE(QLatin1String(log), QLatin1String(want));
184 void KPtyProcessTest::test_ctty()
186 KPtyProcess p;
187 p.setShellCommand("echo this is a test > /dev/tty");
188 p.execute(1000);
189 p.pty()->waitForReadyRead(1000);
190 QString output = p.pty()->readAll();
191 QCOMPARE(output, QLatin1String("this is a test\r\n"));
194 QTEST_KDEMAIN_CORE( KPtyProcessTest )
196 #include "kptyprocesstest.moc"