Instrument Neutral Distributed Interface INDI  2.0.2
TestIndiSetProp.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"
31 #include "IndiServerController.h"
32 #include "ProcessController.h"
33 #include "IndiClientMock.h"
34 
35 // Having a large number of properties ensures cases with buffer not empty on exits occur on server side
36 #define PROP_COUNT 100
37 
38 static void startIndiSetProp(ProcessController & indiSetProp, const std::vector<std::string>& args) {
39  setupSigPipe();
40  std::string indiSetPropPath = getTestExePath("../tools/indi_setprop");
41 
42  indiSetProp.start(indiSetPropPath, args);
43 }
44 
45 static void driverIsAskedProps(DriverMock & fakeDriver) {
46  fakeDriver.cnx.expectXml("<getProperties version='1.7'/>");
47  fprintf(stderr, "getProperties received\n");
48 
49  for(int i = 0; i < PROP_COUNT; ++i) {
50  fakeDriver.cnx.send("<defNumberVector device='fakedev1' name='testnumber" + std::to_string(i) + "' label='test label' group='test_group' state='Idle' perm='rw' timeout='100' timestamp='2018-01-01T00:00:00'>\n");
51  fakeDriver.cnx.send("<defNumber name='content' label='content' min='0' max='100' step='1'>50</defNumber>\n");
52  fakeDriver.cnx.send("</defNumberVector>\n");
53  }
54 }
55 
56 static void startFakeDev1(IndiServerController & indiServer, DriverMock & fakeDriver) {
57  setupSigPipe();
58 
59  fakeDriver.setup();
60 
61  std::string fakeDriverPath = getTestExePath("fakedriver");
62 
63  // Start indiserver with one instance, repeat 0
64  indiServer.startDriver(fakeDriverPath);
65  fprintf(stderr, "indiserver started\n");
66 
67  fakeDriver.waitEstablish();
68  fprintf(stderr, "fake driver started\n");
69 
70  driverIsAskedProps(fakeDriver);
71 }
72 
73 
74 TEST(TestIndiSetProperties, SetFirstPropertyUntyped) {
75  DriverMock fakeDriver;
76  IndiServerController indiServer;
77 
78  startFakeDev1(indiServer, fakeDriver);
79 
80  ProcessController indiSetProp;
81  startIndiSetProp(indiSetProp, { "-p", std::to_string(indiServer.getTcpPort()), "-v", "fakedev1.testnumber0.content=8" });
82 
83  driverIsAskedProps(fakeDriver);
84 
85  indiSetProp.join();
86  indiSetProp.expectExitCode(0);
87 
88  // // Expect the query to come
89  fakeDriver.cnx.expectXml("<newNumberVector device='fakedev1' name='testnumber0'>");
90  fakeDriver.cnx.expectXml("<oneNumber name='content'>");
91  fakeDriver.cnx.expect("\n8");
92  fakeDriver.cnx.expectXml("</oneNumber>");
93  fakeDriver.cnx.expectXml("</newNumberVector>");
94 
95  // Close properly
96  fakeDriver.terminateDriver();
97  // Exit code 1 is expected when driver stopped
98  indiServer.waitProcessEnd(1);
99 
100 }
101 
102 TEST(TestIndiSetProperties, SetFirstPropertyTyped) {
103  DriverMock fakeDriver;
104  IndiServerController indiServer;
105 
106  startFakeDev1(indiServer, fakeDriver);
107 
108  ProcessController indiSetProp;
109  startIndiSetProp(indiSetProp, { "-p", std::to_string(indiServer.getTcpPort()), "-v", "-n", "fakedev1.testnumber0.content=8" });
110 
111  indiSetProp.join();
112  indiSetProp.expectExitCode(0);
113 
114  // // Expect the query to come
115  fakeDriver.cnx.expectXml("<newNumberVector device='fakedev1' name='testnumber0'>");
116  fakeDriver.cnx.expectXml("<oneNumber name='content'>");
117  fakeDriver.cnx.expect("\n8");
118  fakeDriver.cnx.expectXml("</oneNumber>");
119  fakeDriver.cnx.expectXml("</newNumberVector>");
120 
121  // Close properly
122  fakeDriver.terminateDriver();
123  // Exit code 1 is expected when driver stopped
124  indiServer.waitProcessEnd(1);
125 
126 }
127 
128 TEST(TestIndiSetProperties, SetLastProperty) {
129  DriverMock fakeDriver;
130  IndiServerController indiServer;
131 
132  startFakeDev1(indiServer, fakeDriver);
133 
134  ProcessController indiSetProp;
135  startIndiSetProp(indiSetProp, { "-p", std::to_string(indiServer.getTcpPort()), "-v", "fakedev1.testnumber" + std::to_string(PROP_COUNT - 1) + ".content=8" });
136 
137  driverIsAskedProps(fakeDriver);
138 
139  indiSetProp.join();
140  indiSetProp.expectExitCode(0);
141 
142  // // Expect the query to come
143  fakeDriver.cnx.expectXml("<newNumberVector device='fakedev1' name='testnumber" + std::to_string(PROP_COUNT - 1) + "'>");
144  fakeDriver.cnx.expectXml("<oneNumber name='content'>");
145  fakeDriver.cnx.expect("\n8");
146  fakeDriver.cnx.expectXml("</oneNumber>");
147  fakeDriver.cnx.expectXml("</newNumberVector>");
148 
149  // Close properly
150  fakeDriver.terminateDriver();
151  // Exit code 1 is expected when driver stopped
152  indiServer.waitProcessEnd(1);
153 
154 }
155 
156 TEST(TestIndiSetProperties, SetLastPropertyTyped) {
157  DriverMock fakeDriver;
158  IndiServerController indiServer;
159 
160  startFakeDev1(indiServer, fakeDriver);
161 
162  ProcessController indiSetProp;
163  startIndiSetProp(indiSetProp, { "-p", std::to_string(indiServer.getTcpPort()), "-v", "-n", "fakedev1.testnumber" + std::to_string(PROP_COUNT - 1) + ".content=8" });
164 
165  indiSetProp.join();
166  indiSetProp.expectExitCode(0);
167 
168  // // Expect the query to come
169  fakeDriver.cnx.expectXml("<newNumberVector device='fakedev1' name='testnumber" + std::to_string(PROP_COUNT - 1) + "'>");
170  fakeDriver.cnx.expectXml("<oneNumber name='content'>");
171  fakeDriver.cnx.expect("\n8");
172  fakeDriver.cnx.expectXml("</oneNumber>");
173  fakeDriver.cnx.expectXml("</newNumberVector>");
174 
175  // Close properly
176  fakeDriver.terminateDriver();
177  // Exit code 1 is expected when driver stopped
178  indiServer.waitProcessEnd(1);
179 
180 }
TEST(TestIndiSetProperties, SetFirstPropertyUntyped)
#define PROP_COUNT
void expect(const std::string &content)
void send(const std::string &content)
void expectXml(const std::string &xml)
void terminateDriver()
Definition: DriverMock.cpp:56
ConnectionMock cnx
Definition: DriverMock.h:50
void waitEstablish()
Definition: DriverMock.cpp:49
void setup()
Definition: DriverMock.cpp:44
void startDriver(const std::string &driver)
void start(const std::string &path, const std::vector< std::string > &args)
void waitProcessEnd(int expectedExitCode)
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:23613
std::string getTestExePath(const std::string &str)
Definition: utils.cpp:340
void setupSigPipe()
Definition: utils.cpp:37