1 /******************************************************************************
2 
3   This source file is part of the MoleQueue project.
4 
5   Copyright 2012 Kitware, Inc.
6 
7   This source code is released under the New BSD License, (the "License").
8 
9   Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14 
15 ******************************************************************************/
16 
17 #ifndef TESTSERVER_H
18 #define TESTSERVER_H
19 
20 #include <QtCore/QObject>
21 
22 #include <molequeue/servercore/message.h>
23 
24 #include <QtGlobal>
25 
26 #include <QtCore/QDataStream>
27 #include <QtCore/QDateTime>
28 #include <QtCore/QThread>
29 #include <QtCore/QTimer>
30 
31 #include <QtWidgets/QApplication>
32 
33 #include <QtNetwork/QLocalServer>
34 #include <QtNetwork/QLocalSocket>
35 
36 class TestServer : public QObject
37 {
38   Q_OBJECT
39   MoleQueue::PacketType *m_target;
40   QLocalServer *m_server;
41   QLocalSocket *m_socket;
42 public:
43   TestServer(MoleQueue::PacketType *target);
44 
45   ~TestServer();
46 
sendPacket(const MoleQueue::PacketType & packet)47   void sendPacket(const MoleQueue::PacketType &packet)
48   {
49     QDataStream out (m_socket);
50     out.setVersion(QDataStream::Qt_4_7);
51 
52     out << packet;
53     m_socket->flush();
54   }
55 
56   bool waitForConnection(int timeout_ms = 5000)
57   {
58     QTimer timer;
59     timer.setSingleShot(true);
60     timer.start(timeout_ms);
61     while (timer.isActive() && m_socket == NULL) {
62       qApp->processEvents(QEventLoop::AllEvents, 500);
63     }
64     return m_socket != NULL;
65   }
66 
67   bool waitForPacket(int timeout_ms = 5000)
68   {
69     QTimer timer;
70     timer.setSingleShot(true);
71     timer.start(timeout_ms);
72     while (timer.isActive() && m_target->isEmpty()) {
73       qApp->processEvents(QEventLoop::AllEvents, 500);
74     }
75     return !m_target->isEmpty();
76   }
77 
socketName()78   QString socketName() const {return m_server->serverName();}
79 
getRandomSocketName()80   static QString getRandomSocketName()
81   {
82     // Generate a time, process, and thread independent random value.
83     quint32 threadPtr = static_cast<quint32>(
84           reinterpret_cast<qptrdiff>(QThread::currentThread()));
85     quint32 procId = static_cast<quint32>(qApp->applicationPid());
86     quint32 msecs = static_cast<quint32>(
87           QDateTime::currentDateTime().toMSecsSinceEpoch());
88     unsigned int seed = static_cast<unsigned int>(
89           (threadPtr ^ procId) ^ ((msecs << 16) ^ msecs));
90     qDebug() << "Seed:" << seed;
91     qsrand(seed);
92     int randVal = qrand();
93 
94     return QString("MoleQueue-testing-%1").arg(QString::number(randVal));
95   }
96 
97 private slots:
newConnection()98   void newConnection()
99   {
100     m_socket = m_server->nextPendingConnection();
101     connect(m_socket, SIGNAL(disconnected()), m_socket, SLOT(deleteLater()));
102     connect(m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
103   }
104 
readyRead()105   void readyRead()
106   {
107 //  qDebug() << "Test server received" << m_socket->bytesAvailable() << "bytes.";
108     QDataStream in (m_socket);
109     in.setVersion(QDataStream::Qt_4_7);
110 
111     MoleQueue::PacketType packet;
112 
113     in >> *m_target;
114   }
115 };
116 
117 #endif // TESTSERVER_H
118