1/**
2 * Copyright (C) 2007 Brad Hards <bradh@frogmouth.net>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <QtCrypto>
27#include <QtTest/QtTest>
28
29#ifdef QT_STATICPLUGIN
30#include "import_plugins.h"
31#endif
32
33#include <memory>
34
35class PipeUnitTest : public QObject
36{
37 Q_OBJECT
38
39private Q_SLOTS:
40 void initTestCase();
41 void cleanupTestCase();
42 void createPipeWithInsecureMemory();
43 void createPipeWithSecureMemory();
44 void readWrite();
45 void readWriteSecure();
46 void signalTests();
47 void signalTestsSecure();
48
49private:
50 QCA::Initializer *m_init;
51};
52
53void PipeUnitTest::initTestCase()
54{
55 m_init = new QCA::Initializer;
56}
57
58void PipeUnitTest::cleanupTestCase()
59{
60 QCA::unloadAllPlugins();
61 delete m_init;
62}
63
64void PipeUnitTest::createPipeWithInsecureMemory()
65{
66 QCA::QPipe pipe1;
67 // we haven't created the pipe yet, so it shouldn't be valid
68 QCOMPARE(pipe1.readEnd().isValid(), false);
69 QCOMPARE(pipe1.writeEnd().isValid(), false);
70
71 pipe1.create(); // insecure memory used
72 QVERIFY(pipe1.readEnd().isValid());
73 QVERIFY(pipe1.readEnd().type() == QCA::QPipeDevice::Read);
74 QVERIFY(pipe1.writeEnd().isValid());
75 QVERIFY(pipe1.writeEnd().type() == QCA::QPipeDevice::Write);
76
77 pipe1.reset();
78 QCOMPARE(pipe1.readEnd().isValid(), false);
79 QCOMPARE(pipe1.writeEnd().isValid(), false);
80}
81
82void PipeUnitTest::createPipeWithSecureMemory()
83{
84 QCA::QPipe pipe1;
85 // we haven't created the pipe yet, so it shouldn't be valid
86 QCOMPARE(pipe1.readEnd().isValid(), false);
87 QCOMPARE(pipe1.writeEnd().isValid(), false);
88
89 pipe1.create(secure: true); // secure memory used
90 QVERIFY(pipe1.readEnd().isValid());
91 QVERIFY(pipe1.readEnd().type() == QCA::QPipeDevice::Read);
92 QVERIFY(pipe1.writeEnd().isValid());
93 QVERIFY(pipe1.writeEnd().type() == QCA::QPipeDevice::Write);
94
95 pipe1.reset();
96 QCOMPARE(pipe1.readEnd().isValid(), false);
97 QCOMPARE(pipe1.writeEnd().isValid(), false);
98}
99
100void PipeUnitTest::readWrite()
101{
102 QCA::QPipe pipe1;
103 QByteArray testData1("Down the");
104 QByteArray testData2("pipe!");
105
106 pipe1.create();
107 QVERIFY(pipe1.writeEnd().isValid());
108 QVERIFY(pipe1.readEnd().isValid());
109
110 // enable the pipe ends for read/write
111 pipe1.writeEnd().enable();
112 pipe1.readEnd().enable();
113
114 pipe1.writeEnd().write(a: testData1);
115 QTest::qWait(ms: 1); // process events
116 QTest::qWait(ms: 1); // process events
117 QByteArray out1 = pipe1.readEnd().read(); // read all...
118 QCOMPARE(testData1, out1);
119
120 pipe1.writeEnd().write(a: testData1); // put it back in
121 QTest::qWait(ms: 1); // process events
122 QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size());
123
124 pipe1.writeEnd().write(a: testData2); // add some more data
125 QTest::qWait(ms: 1); // process events
126 QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size() + testData2.size());
127 QByteArray thisRead = pipe1.readEnd().read(bytes: 1);
128 QCOMPARE(thisRead, QByteArray("D"));
129 thisRead = pipe1.readEnd().read(bytes: 3);
130 QCOMPARE(thisRead, QByteArray("own"));
131 thisRead = pipe1.readEnd().read();
132 QCOMPARE(thisRead, QByteArray(" thepipe!"));
133}
134
135void PipeUnitTest::readWriteSecure()
136{
137 QCA::QPipe pipe1;
138 QCA::SecureArray testData1("Down the");
139 QCA::SecureArray testData2(" secure pipe!");
140
141 pipe1.create(secure: true);
142 QVERIFY(pipe1.writeEnd().isValid());
143 QVERIFY(pipe1.readEnd().isValid());
144
145 // enable the pipe ends for read/write
146 pipe1.writeEnd().enable();
147 pipe1.readEnd().enable();
148
149 pipe1.writeEnd().writeSecure(a: testData1);
150 QTest::qWait(ms: 1); // process events
151 QTest::qWait(ms: 1); // process events
152 QCA::SecureArray out1 = pipe1.readEnd().readSecure(); // read all...
153 QCOMPARE(testData1, out1);
154
155 pipe1.writeEnd().writeSecure(a: testData1); // put it back in
156 QTest::qWait(ms: 1); // process events
157 QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size());
158
159 pipe1.writeEnd().writeSecure(a: testData2); // add some more data
160 QTest::qWait(ms: 1); // process events
161 QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size() + testData2.size());
162 QCA::SecureArray thisRead = pipe1.readEnd().readSecure(bytes: 1);
163 QCOMPARE(thisRead, QCA::SecureArray("D"));
164 thisRead = pipe1.readEnd().readSecure(bytes: 3);
165 QCOMPARE(thisRead, QCA::SecureArray("own"));
166 thisRead = pipe1.readEnd().readSecure();
167 QCOMPARE(thisRead, QCA::SecureArray(" the secure pipe!"));
168}
169
170void PipeUnitTest::signalTests()
171{
172 std::unique_ptr<QCA::QPipe> pipe(new QCA::QPipe);
173 pipe->create();
174
175 QVERIFY(pipe->writeEnd().isValid());
176 pipe->writeEnd().enable();
177 QVERIFY(pipe->readEnd().isValid());
178 pipe->readEnd().enable();
179
180 QSignalSpy readyReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::readyRead);
181 QVERIFY(readyReadSpy.isValid());
182 QSignalSpy bytesWrittenSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::bytesWritten);
183 QVERIFY(bytesWrittenSpy.isValid());
184 QSignalSpy closedWriteSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::closed);
185 QVERIFY(closedWriteSpy.isValid());
186 QSignalSpy closedReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::closed);
187 QVERIFY(closedReadSpy.isValid());
188
189 QCOMPARE(readyReadSpy.count(), 0);
190 QCOMPARE(bytesWrittenSpy.count(), 0);
191 QCOMPARE(closedWriteSpy.count(), 0);
192 QCOMPARE(closedReadSpy.count(), 0);
193
194 QByteArray data("Far better, it is, to dare mighty things");
195 pipe->writeEnd().write(a: data);
196 QTest::qWait(ms: 1);
197 QTest::qWait(ms: 1);
198 QCOMPARE(readyReadSpy.count(), 1);
199 QCOMPARE(bytesWrittenSpy.count(), 1);
200 // this pulls out the first argument to the first signal as an integer
201 QCOMPARE(bytesWrittenSpy.takeFirst().at(0).toInt(), data.size());
202 QCOMPARE(pipe->readEnd().bytesAvailable(), data.size());
203
204 QCOMPARE(closedWriteSpy.count(), 0);
205 QCOMPARE(closedReadSpy.count(), 0);
206
207 pipe->readEnd().close();
208 QTest::qWait(ms: 1);
209 QCOMPARE(closedWriteSpy.count(), 0);
210 QCOMPARE(closedReadSpy.count(), 1);
211 pipe->writeEnd().close();
212 QTest::qWait(ms: 1);
213 QCOMPARE(closedWriteSpy.count(), 1);
214 QCOMPARE(closedReadSpy.count(), 1);
215}
216
217void PipeUnitTest::signalTestsSecure()
218{
219 std::unique_ptr<QCA::QPipe> pipe(new QCA::QPipe);
220 pipe->create(secure: true);
221
222 QVERIFY(pipe->writeEnd().isValid());
223 pipe->writeEnd().enable();
224 QVERIFY(pipe->readEnd().isValid());
225 pipe->readEnd().enable();
226
227 QSignalSpy readyReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::readyRead);
228 QVERIFY(readyReadSpy.isValid());
229 QSignalSpy bytesWrittenSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::bytesWritten);
230 QVERIFY(bytesWrittenSpy.isValid());
231 QSignalSpy closedWriteSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::closed);
232 QVERIFY(closedWriteSpy.isValid());
233 QSignalSpy closedReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::closed);
234 QVERIFY(closedReadSpy.isValid());
235
236 QCOMPARE(readyReadSpy.count(), 0);
237 QCOMPARE(bytesWrittenSpy.count(), 0);
238 QCOMPARE(closedWriteSpy.count(), 0);
239 QCOMPARE(closedReadSpy.count(), 0);
240
241 QCA::SecureArray data("Far better, it is, to dare mighty things");
242 pipe->writeEnd().writeSecure(a: data);
243 QTest::qWait(ms: 1);
244 QTest::qWait(ms: 1);
245 QCOMPARE(readyReadSpy.count(), 1);
246 QCOMPARE(bytesWrittenSpy.count(), 1);
247 // this pulls out the first argument to the first signal as an integer
248 QCOMPARE(bytesWrittenSpy.takeFirst().at(0).toInt(), data.size());
249 QCOMPARE(pipe->readEnd().bytesAvailable(), data.size());
250
251 QCOMPARE(closedWriteSpy.count(), 0);
252 QCOMPARE(closedReadSpy.count(), 0);
253
254 pipe->readEnd().close();
255 QTest::qWait(ms: 1);
256 QCOMPARE(closedWriteSpy.count(), 0);
257 QCOMPARE(closedReadSpy.count(), 1);
258 pipe->writeEnd().close();
259 QTest::qWait(ms: 1);
260 QCOMPARE(closedWriteSpy.count(), 1);
261 QCOMPARE(closedReadSpy.count(), 1);
262}
263
264QTEST_MAIN(PipeUnitTest)
265
266#include "pipeunittest.moc"
267

source code of qca/unittest/pipeunittest/pipeunittest.cpp