File indexing completed on 2024-04-28 04:44:10

0001 /**
0002  * Copyright (C)  2007  Brad Hards <bradh@frogmouth.net>
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  *
0008  * 1. Redistributions of source code must retain the above copyright
0009  *   notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *   notice, this list of conditions and the following disclaimer in the
0012  *   documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0015  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0016  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0017  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0018  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0019  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0020  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0021  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0023  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #include <QtCrypto>
0027 #include <QtTest/QtTest>
0028 
0029 #ifdef QT_STATICPLUGIN
0030 #include "import_plugins.h"
0031 #endif
0032 
0033 #include <memory>
0034 
0035 class PipeUnitTest : public QObject
0036 {
0037     Q_OBJECT
0038 
0039 private Q_SLOTS:
0040     void initTestCase();
0041     void cleanupTestCase();
0042     void createPipeWithInsecureMemory();
0043     void createPipeWithSecureMemory();
0044     void readWrite();
0045     void readWriteSecure();
0046     void signalTests();
0047     void signalTestsSecure();
0048 
0049 private:
0050     QCA::Initializer *m_init;
0051 };
0052 
0053 void PipeUnitTest::initTestCase()
0054 {
0055     m_init = new QCA::Initializer;
0056 }
0057 
0058 void PipeUnitTest::cleanupTestCase()
0059 {
0060     QCA::unloadAllPlugins();
0061     delete m_init;
0062 }
0063 
0064 void PipeUnitTest::createPipeWithInsecureMemory()
0065 {
0066     QCA::QPipe pipe1;
0067     // we haven't created the pipe yet, so it shouldn't be valid
0068     QCOMPARE(pipe1.readEnd().isValid(), false);
0069     QCOMPARE(pipe1.writeEnd().isValid(), false);
0070 
0071     pipe1.create(); // insecure memory used
0072     QVERIFY(pipe1.readEnd().isValid());
0073     QVERIFY(pipe1.readEnd().type() == QCA::QPipeDevice::Read);
0074     QVERIFY(pipe1.writeEnd().isValid());
0075     QVERIFY(pipe1.writeEnd().type() == QCA::QPipeDevice::Write);
0076 
0077     pipe1.reset();
0078     QCOMPARE(pipe1.readEnd().isValid(), false);
0079     QCOMPARE(pipe1.writeEnd().isValid(), false);
0080 }
0081 
0082 void PipeUnitTest::createPipeWithSecureMemory()
0083 {
0084     QCA::QPipe pipe1;
0085     // we haven't created the pipe yet, so it shouldn't be valid
0086     QCOMPARE(pipe1.readEnd().isValid(), false);
0087     QCOMPARE(pipe1.writeEnd().isValid(), false);
0088 
0089     pipe1.create(true); // secure memory used
0090     QVERIFY(pipe1.readEnd().isValid());
0091     QVERIFY(pipe1.readEnd().type() == QCA::QPipeDevice::Read);
0092     QVERIFY(pipe1.writeEnd().isValid());
0093     QVERIFY(pipe1.writeEnd().type() == QCA::QPipeDevice::Write);
0094 
0095     pipe1.reset();
0096     QCOMPARE(pipe1.readEnd().isValid(), false);
0097     QCOMPARE(pipe1.writeEnd().isValid(), false);
0098 }
0099 
0100 void PipeUnitTest::readWrite()
0101 {
0102     QCA::QPipe pipe1;
0103     QByteArray testData1("Down the");
0104     QByteArray testData2("pipe!");
0105 
0106     pipe1.create();
0107     QVERIFY(pipe1.writeEnd().isValid());
0108     QVERIFY(pipe1.readEnd().isValid());
0109 
0110     // enable the pipe ends for read/write
0111     pipe1.writeEnd().enable();
0112     pipe1.readEnd().enable();
0113 
0114     pipe1.writeEnd().write(testData1);
0115     QTest::qWait(1);                          // process events
0116     QTest::qWait(1);                          // process events
0117     QByteArray out1 = pipe1.readEnd().read(); // read all...
0118     QCOMPARE(testData1, out1);
0119 
0120     pipe1.writeEnd().write(testData1); // put it back in
0121     QTest::qWait(1);                   // process events
0122     QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size());
0123 
0124     pipe1.writeEnd().write(testData2); // add some more data
0125     QTest::qWait(1);                   // process events
0126     QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size() + testData2.size());
0127     QByteArray thisRead = pipe1.readEnd().read(1);
0128     QCOMPARE(thisRead, QByteArray("D"));
0129     thisRead = pipe1.readEnd().read(3);
0130     QCOMPARE(thisRead, QByteArray("own"));
0131     thisRead = pipe1.readEnd().read();
0132     QCOMPARE(thisRead, QByteArray(" thepipe!"));
0133 }
0134 
0135 void PipeUnitTest::readWriteSecure()
0136 {
0137     QCA::QPipe       pipe1;
0138     QCA::SecureArray testData1("Down the");
0139     QCA::SecureArray testData2(" secure pipe!");
0140 
0141     pipe1.create(true);
0142     QVERIFY(pipe1.writeEnd().isValid());
0143     QVERIFY(pipe1.readEnd().isValid());
0144 
0145     // enable the pipe ends for read/write
0146     pipe1.writeEnd().enable();
0147     pipe1.readEnd().enable();
0148 
0149     pipe1.writeEnd().writeSecure(testData1);
0150     QTest::qWait(1);                                      // process events
0151     QTest::qWait(1);                                      // process events
0152     QCA::SecureArray out1 = pipe1.readEnd().readSecure(); // read all...
0153     QCOMPARE(testData1, out1);
0154 
0155     pipe1.writeEnd().writeSecure(testData1); // put it back in
0156     QTest::qWait(1);                         // process events
0157     QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size());
0158 
0159     pipe1.writeEnd().writeSecure(testData2); // add some more data
0160     QTest::qWait(1);                         // process events
0161     QCOMPARE(pipe1.readEnd().bytesAvailable(), testData1.size() + testData2.size());
0162     QCA::SecureArray thisRead = pipe1.readEnd().readSecure(1);
0163     QCOMPARE(thisRead, QCA::SecureArray("D"));
0164     thisRead = pipe1.readEnd().readSecure(3);
0165     QCOMPARE(thisRead, QCA::SecureArray("own"));
0166     thisRead = pipe1.readEnd().readSecure();
0167     QCOMPARE(thisRead, QCA::SecureArray(" the secure pipe!"));
0168 }
0169 
0170 void PipeUnitTest::signalTests()
0171 {
0172     std::unique_ptr<QCA::QPipe> pipe(new QCA::QPipe);
0173     pipe->create();
0174 
0175     QVERIFY(pipe->writeEnd().isValid());
0176     pipe->writeEnd().enable();
0177     QVERIFY(pipe->readEnd().isValid());
0178     pipe->readEnd().enable();
0179 
0180     QSignalSpy readyReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::readyRead);
0181     QVERIFY(readyReadSpy.isValid());
0182     QSignalSpy bytesWrittenSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::bytesWritten);
0183     QVERIFY(bytesWrittenSpy.isValid());
0184     QSignalSpy closedWriteSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::closed);
0185     QVERIFY(closedWriteSpy.isValid());
0186     QSignalSpy closedReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::closed);
0187     QVERIFY(closedReadSpy.isValid());
0188 
0189     QCOMPARE(readyReadSpy.count(), 0);
0190     QCOMPARE(bytesWrittenSpy.count(), 0);
0191     QCOMPARE(closedWriteSpy.count(), 0);
0192     QCOMPARE(closedReadSpy.count(), 0);
0193 
0194     QByteArray data("Far better, it is, to dare mighty things");
0195     pipe->writeEnd().write(data);
0196     QTest::qWait(1);
0197     QTest::qWait(1);
0198     QCOMPARE(readyReadSpy.count(), 1);
0199     QCOMPARE(bytesWrittenSpy.count(), 1);
0200     // this pulls out the first argument to the first signal as an integer
0201     QCOMPARE(bytesWrittenSpy.takeFirst().at(0).toInt(), data.size());
0202     QCOMPARE(pipe->readEnd().bytesAvailable(), data.size());
0203 
0204     QCOMPARE(closedWriteSpy.count(), 0);
0205     QCOMPARE(closedReadSpy.count(), 0);
0206 
0207     pipe->readEnd().close();
0208     QTest::qWait(1);
0209     QCOMPARE(closedWriteSpy.count(), 0);
0210     QCOMPARE(closedReadSpy.count(), 1);
0211     pipe->writeEnd().close();
0212     QTest::qWait(1);
0213     QCOMPARE(closedWriteSpy.count(), 1);
0214     QCOMPARE(closedReadSpy.count(), 1);
0215 }
0216 
0217 void PipeUnitTest::signalTestsSecure()
0218 {
0219     std::unique_ptr<QCA::QPipe> pipe(new QCA::QPipe);
0220     pipe->create(true);
0221 
0222     QVERIFY(pipe->writeEnd().isValid());
0223     pipe->writeEnd().enable();
0224     QVERIFY(pipe->readEnd().isValid());
0225     pipe->readEnd().enable();
0226 
0227     QSignalSpy readyReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::readyRead);
0228     QVERIFY(readyReadSpy.isValid());
0229     QSignalSpy bytesWrittenSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::bytesWritten);
0230     QVERIFY(bytesWrittenSpy.isValid());
0231     QSignalSpy closedWriteSpy(&(pipe->writeEnd()), &QCA::QPipeEnd::closed);
0232     QVERIFY(closedWriteSpy.isValid());
0233     QSignalSpy closedReadSpy(&(pipe->readEnd()), &QCA::QPipeEnd::closed);
0234     QVERIFY(closedReadSpy.isValid());
0235 
0236     QCOMPARE(readyReadSpy.count(), 0);
0237     QCOMPARE(bytesWrittenSpy.count(), 0);
0238     QCOMPARE(closedWriteSpy.count(), 0);
0239     QCOMPARE(closedReadSpy.count(), 0);
0240 
0241     QCA::SecureArray data("Far better, it is, to dare mighty things");
0242     pipe->writeEnd().writeSecure(data);
0243     QTest::qWait(1);
0244     QTest::qWait(1);
0245     QCOMPARE(readyReadSpy.count(), 1);
0246     QCOMPARE(bytesWrittenSpy.count(), 1);
0247     // this pulls out the first argument to the first signal as an integer
0248     QCOMPARE(bytesWrittenSpy.takeFirst().at(0).toInt(), data.size());
0249     QCOMPARE(pipe->readEnd().bytesAvailable(), data.size());
0250 
0251     QCOMPARE(closedWriteSpy.count(), 0);
0252     QCOMPARE(closedReadSpy.count(), 0);
0253 
0254     pipe->readEnd().close();
0255     QTest::qWait(1);
0256     QCOMPARE(closedWriteSpy.count(), 0);
0257     QCOMPARE(closedReadSpy.count(), 1);
0258     pipe->writeEnd().close();
0259     QTest::qWait(1);
0260     QCOMPARE(closedWriteSpy.count(), 1);
0261     QCOMPARE(closedReadSpy.count(), 1);
0262 }
0263 
0264 QTEST_MAIN(PipeUnitTest)
0265 
0266 #include "pipeunittest.moc"