File indexing completed on 2024-05-12 17:15:20

0001 /*
0002    Copyright (C) 2013 Andreas Hartmetz <ahartmetz@gmail.com>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LGPL.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 
0019    Alternatively, this file is available under the Mozilla Public License
0020    Version 1.1.  You may obtain a copy of the License at
0021    http://www.mozilla.org/MPL/
0022 */
0023 
0024 #include "arguments.h"
0025 #include "connectaddress.h"
0026 #include "eventdispatcher.h"
0027 #include "imessagereceiver.h"
0028 #include "message.h"
0029 #include "pendingreply.h"
0030 #include "connection.h"
0031 
0032 #include "../testutil.h"
0033 
0034 #include <iostream>
0035 #include <string>
0036 
0037 static void addressMessageToBus(Message *msg)
0038 {
0039     msg->setType(Message::MethodCallMessage);
0040     msg->setDestination("org.freedesktop.DBus");
0041     msg->setInterface("org.freedesktop.DBus");
0042     msg->setPath("/org/freedesktop/DBus");
0043 }
0044 
0045 class ReplyCheck : public IMessageReceiver
0046 {
0047 public:
0048     void handlePendingReplyFinished(PendingReply *pr, Connection *connection) override
0049     {
0050         pr->dumpState();
0051         TEST(pr->isFinished());
0052         TEST(!pr->isError());
0053 
0054         std::cout << "got it!\n" << pr->reply()->arguments().prettyPrint();
0055 
0056         // This is really a different test, it used to reproduce a memory leak under Valgrind
0057         Message reply = pr->takeReply();
0058 
0059         connection->eventDispatcher()->interrupt();
0060     }
0061 };
0062 
0063 static void testBusAddress(bool waitForConnected)
0064 {
0065     EventDispatcher eventDispatcher;
0066     Connection conn(&eventDispatcher, ConnectAddress::StandardBus::Session);
0067 
0068     Message msg;
0069     addressMessageToBus(&msg);
0070     msg.setMethod("RequestName");
0071 
0072     Arguments::Writer writer;
0073     writer.writeString("Bana.nana"); // requested name
0074     writer.writeUint32(4); // TODO proper enum or so: 4 == DBUS_NAME_FLAG_DO_NOT_QUEUE
0075     msg.setArguments(writer.finish());
0076 
0077     if (waitForConnected) {
0078         // finish creating the connection
0079         while (conn.uniqueName().empty()) {
0080             eventDispatcher.poll();
0081         }
0082     }
0083 
0084     PendingReply busNameReply = conn.send(std::move(msg));
0085     ReplyCheck replyCheck;
0086     busNameReply.setReceiver(&replyCheck);
0087 
0088     while (eventDispatcher.poll()) {
0089     }
0090 }
0091 
0092 class TimeoutCheck : public IMessageReceiver
0093 {
0094 public:
0095     void handlePendingReplyFinished(PendingReply *reply, Connection *connection) override
0096     {
0097         TEST(reply->isFinished());
0098         TEST(!reply->hasNonErrorReply());
0099         TEST(reply->error().code() == Error::Timeout);
0100         std::cout << "We HAVE timed out.\n";
0101         connection->eventDispatcher()->interrupt();
0102     }
0103 };
0104 
0105 static void testTimeout()
0106 {
0107     EventDispatcher eventDispatcher;
0108     Connection conn(&eventDispatcher, ConnectAddress::StandardBus::Session);
0109 
0110     // finish creating the connection; we need to know our own name so we can send the message to
0111     // ourself so we can make sure that there will be no reply :)
0112     while (conn.uniqueName().empty()) {
0113         eventDispatcher.poll();
0114     }
0115 
0116     Message msg = Message::createCall("/some/dummy/path", "org.no_interface", "non_existent_method");
0117     msg.setDestination(conn.uniqueName());
0118 
0119     PendingReply neverGonnaGetReply = conn.send(std::move(msg), 200);
0120     TimeoutCheck timeoutCheck;
0121     neverGonnaGetReply.setReceiver(&timeoutCheck);
0122 
0123     while (eventDispatcher.poll()) {
0124     }
0125 }
0126 
0127 int main(int, char *[])
0128 {
0129     testBusAddress(false);
0130     testBusAddress(true);
0131     testTimeout();
0132     // TODO testBadCall
0133     std::cout << "Passed!\n";
0134 }