Instrument Neutral Distributed Interface INDI 2.2.5
TestClientQueries.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Copyright(c) 2022 Ludovic Pollet. All rights reserved.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17*******************************************************************************/
18
19#include <stdexcept>
20#include <stdio.h>
21#include <unistd.h>
22#include <sys/types.h>
23#include <system_error>
24
25#include "gtest/gtest.h"
26
27#include "utils.h"
28
29#include "SharedBuffer.h"
30#include "DriverMock.h"
32#include "IndiClientMock.h"
33
34#define PROP_COUNT 5
35
36static void driverSendsProps(DriverMock &fakeDriver)
37{
38 fprintf(stderr, "Driver sends properties\n");
39 for(int i = 0; i < PROP_COUNT; ++i)
40 {
41 fakeDriver.cnx.send("<defNumberVector device='fakedev1' name='testnumber" + std::to_string(
42 i) + "' label='test label' group='test_group' state='Idle' perm='rw' timeout='100' timestamp='2018-01-01T00:00:00'>\n");
43 fakeDriver.cnx.send("<defNumber name='content' label='content' min='0' max='100' step='1'>50</defNumber>\n");
44 fakeDriver.cnx.send("</defNumberVector>\n");
45 }
46}
47
48static void clientReceivesProps(IndiClientMock &indiClient)
49{
50 fprintf(stderr, "Client receives properties\n");
51 for(int i = 0; i < PROP_COUNT; ++i)
52 {
53 indiClient.cnx.expectXml("<defNumberVector device='fakedev1' name='testnumber" + std::to_string(
54 i) + "' label='test label' group='test_group' state='Idle' perm='rw' timeout='100' timestamp='2018-01-01T00:00:00'>");
55 indiClient.cnx.expectXml("<defNumber name='content' label='content' min='0' max='100' step='1'>");
56 indiClient.cnx.expect("\n50");
57 indiClient.cnx.expectXml("</defNumber>");
58 indiClient.cnx.expectXml("</defNumberVector>");
59 }
60}
61
62
63static void startFakeDev1(IndiServerController &indiServer, DriverMock &fakeDriver)
64{
66
67 fakeDriver.setup();
68
69 std::string fakeDriverPath = FAKEDRIVER_PATH;
70
71 // Start indiserver with one instance, repeat 0
72 indiServer.startDriver(fakeDriverPath);
73 fprintf(stderr, "indiserver started\n");
74
75 fakeDriver.waitEstablish();
76 fprintf(stderr, "fake driver started\n");
77
78 fakeDriver.cnx.expectXml("<getProperties version='1.7'/>");
79 fprintf(stderr, "getProperties received\n");
80
81 driverSendsProps(fakeDriver);
82}
83
84static void connectFakeDev1Client(IndiServerController &, DriverMock &fakeDriver, IndiClientMock &indiClient)
85{
86 fprintf(stderr, "Client asks properties\n");
87 indiClient.cnx.send("<getProperties version='1.7'/>\n");
88 fakeDriver.cnx.expectXml("<getProperties version='1.7'/>");
89
90 driverSendsProps(fakeDriver);
91 fprintf(stderr, "Driver sends properties\n");
92
93 fprintf(stderr, "Client receive properties\n");
94 clientReceivesProps(indiClient);
95}
96
97TEST(TestClientQueries, ServerForwardRequest)
98{
99 DriverMock fakeDriver;
100 IndiServerController indiServer;
101
102 startFakeDev1(indiServer, fakeDriver);
103
104 IndiClientMock indiClient;
105
106 indiClient.connect(indiServer);
107
108 connectFakeDev1Client(indiServer, fakeDriver, indiClient);
109
110 indiClient.cnx.send("<newNumberVector device='fakedev1' name='testnumber' timestamp='2018-01-01T00:00:00'>");
111 indiClient.cnx.send("<oneNumber name='content' > 51 </oneNumber>");
112 indiClient.cnx.send("</newNumberVector>");
113
114 fakeDriver.cnx.expectXml("<newNumberVector device='fakedev1' name='testnumber' timestamp='2018-01-01T00:00:00'>");
115 fakeDriver.cnx.expectXml("<oneNumber name='content'>");
116 fakeDriver.cnx.expect("\n51");
117 fakeDriver.cnx.expectXml("</oneNumber>");
118 fakeDriver.cnx.expectXml("</newNumberVector>");
119
120 fakeDriver.terminateDriver();
121 // Exit code 1 is expected when driver stopped
122 indiServer.waitProcessEnd(1);
123
124}
125
126TEST(TestClientQueries, ServerForwardRequestOfHalfDeadClient)
127{
128 DriverMock fakeDriver;
129 IndiServerController indiServer;
130
131 startFakeDev1(indiServer, fakeDriver);
132
133 IndiClientMock indiClient;
134
135 indiClient.connect(indiServer);
136
137 connectFakeDev1Client(indiServer, fakeDriver, indiClient);
138
139 indiClient.cnx.send("<getProperties version='1.7'/>\n");
140 fakeDriver.cnx.expectXml("<getProperties version='1.7'/>");
141
142 driverSendsProps(fakeDriver);
143
144 // Make sure the server is sync with the client before shutdown. Get a full interaction with it
145 fakeDriver.cnx.send("<pingRequest uid='1'/>\n");
146 fakeDriver.cnx.expectXml("<pingReply uid='1'/>");
147
148 indiClient.cnx.send("<newNumberVector device='fakedev1' name='testnumber' timestamp='2018-01-01T00:00:00'>");
149 indiClient.cnx.send("<oneNumber name='content' > 51 </oneNumber>");
150 indiClient.cnx.send("</newNumberVector>");
151
152 // Client is done writing.
153 indiClient.cnx.shutdown(false, true);
154
155 fakeDriver.cnx.expectXml("<newNumberVector device='fakedev1' name='testnumber' timestamp='2018-01-01T00:00:00'>");
156 fakeDriver.cnx.expectXml("<oneNumber name='content'>");
157 fakeDriver.cnx.expect("\n51");
158 fakeDriver.cnx.expectXml("</oneNumber>");
159 fakeDriver.cnx.expectXml("</newNumberVector>");
160
161 indiClient.close();
162
163 fakeDriver.terminateDriver();
164 // Exit code 1 is expected when driver stopped
165 indiServer.waitProcessEnd(1);
166}
TEST(TestClientQueries, ServerForwardRequest)
#define PROP_COUNT
void shutdown(bool rd, bool wr)
void expect(const std::string &content)
void send(const std::string &content)
void expectXml(const std::string &xml)
void terminateDriver()
ConnectionMock cnx
Definition DriverMock.h:50
void waitEstablish()
void setup()
ConnectionMock cnx
void connect(const IndiServerController &server)
void startDriver(const std::string &driver)
void waitProcessEnd(int expectedExitCode)
void setupSigPipe()
Definition utils.cpp:37