/[svn]/linuxsampler/trunk/src/testcases/LSCPTest.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/testcases/LSCPTest.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 211 - (show annotations) (download)
Sun Jul 25 23:27:41 2004 UTC (19 years, 9 months ago) by schoenebeck
File size: 9056 byte(s)
* src/linuxsampler.cpp: tidied up a bit, "initialization completed"
  message shown only after the server is actually running
* src/testcases/: print the name of each test suite before running the
  tests of the suite, added first tests against the LSCP server using a
  socket connection to the LSCP server (tests for the following LSCP
  commands: "ADD CHANNEL", "GET CHANNELS", "REMOVE CHANNEL")

1 #include "LSCPTest.h"
2
3 #include <iostream>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 CPPUNIT_TEST_SUITE_REGISTRATION(LSCPTest);
8
9 // Note:
10 // we have to declare all those variables which we want to use for all
11 // tests within this test suite static because there are side effects which
12 // occur on transition to the next test which would change the values of our
13 // variables
14 static Sampler* pSampler = NULL;
15 static LSCPServer* pLSCPServer = NULL;
16 static int hSocket = -1;
17 static FILE* hServerIn = NULL;
18
19 // split the multi line response string into the individual lines and remove the last (delimiter) line and the line feed characters in all lines
20 static vector<string> __ConvertMultiLineMessage(string msg) {
21 vector<string> res;
22
23 // erase the (dot) delimiter line
24 static const string dotlinedelimiter = ".\r\n";
25 string::size_type pos = msg.rfind(dotlinedelimiter);
26 msg = msg.replace(pos, dotlinedelimiter.length(), "");
27
28 // now split the lines
29 static const string linedelimiter = "\r\n";
30 while (true) {
31 pos = msg.find(linedelimiter, 0);
32
33 if (pos == string::npos) break; // if we're done
34
35 // get the line without the line feed and put it at the end of the vector
36 string line = msg.substr(0, pos);
37 res.push_back(line);
38
39 // remove the line from the input string
40 pos += linedelimiter.length();
41 msg = msg.substr(pos, msg.length() - pos);
42 }
43
44 return res;
45 }
46
47
48 // LSCPTest
49
50 // returns false if the server could not be launched
51 bool LSCPTest::launchLSCPServer() {
52 const long timeout_seconds = 10; // we give the server max. 10 seconds to startup, otherwise we declare the startup as failed
53 try {
54 pSampler = new Sampler;
55 pLSCPServer = new LSCPServer(pSampler);
56 pLSCPServer->StartThread();
57 int res = pLSCPServer->WaitUntilInitialized(timeout_seconds);
58 if (res < 0) throw;
59
60 return true; // success
61 }
62 catch (...) {
63 pSampler = NULL;
64 pLSCPServer = NULL;
65 return false; // failure
66 }
67 }
68
69 // returns false if the server could not be destroyed without problems
70 bool LSCPTest::shutdownLSCPServer() {
71 try {
72 pLSCPServer->StopThread();
73 if (pLSCPServer) {
74 delete pLSCPServer;
75 pLSCPServer = NULL;
76 }
77 if (pSampler) {
78 delete pSampler;
79 pSampler = NULL;
80 }
81 return true; // success
82 }
83 catch (...) {
84 return false; // failure
85 }
86 }
87
88 // returns false if client connection to the LSCP server could not be established
89 bool LSCPTest::connectToLSCPServer() {
90 const int iPort = LSCP_PORT; // LSCP server listening port (from lscpserver.h)
91 hSocket = -1;
92
93 hostent* pHost = gethostbyname("localhost");
94 if (pHost == NULL) return false;
95
96 hSocket = socket(AF_INET, SOCK_STREAM, 0);
97 if (hSocket < 0) return false;
98
99 sockaddr_in addr;
100 memset((char*) &addr, 0, sizeof(sockaddr_in));
101 addr.sin_family = pHost->h_addrtype;
102 memmove((char*) &(addr.sin_addr), pHost->h_addr, pHost->h_length);
103 addr.sin_port = htons((short) iPort);
104
105 if (connect(hSocket, (sockaddr*) &addr, sizeof(sockaddr_in)) < 0) {
106 close(hSocket);
107 return false;
108 }
109
110 hServerIn = fdopen(hSocket, "r");
111
112 return true;
113 }
114
115 bool LSCPTest::closeConnectionToLSCPServer() {
116 //cout << "closeConnectionToLSCPServer()\n" << flush;
117 hServerIn = NULL;
118 if (hSocket >= 0) {
119 close(hSocket);
120 hSocket = -1;
121 }
122 return true;
123 }
124
125 // send a command to the LSCP server
126 void LSCPTest::sendCommandToLSCPServer(string cmd) {
127 if (hSocket < 0) {
128 cout << "sendCommandToLSCPServer() error: client socket not ready\n" << flush;
129 return;
130 }
131 cmd += "\r\n";
132 send(hSocket, cmd.c_str(), cmd.length(), 0);
133 }
134
135 // wait until LSCP server answers with a single line answer
136 string LSCPTest::receiveSingleLineAnswerFromLSCPServer() {
137 string msg = receiveAnswerFromLSCPServer("\n");
138 // remove the line feed at the end
139 static const string linedelimiter = "\r\n";
140 string::size_type pos = msg.rfind(linedelimiter);
141 return msg.substr(0, pos);
142 }
143
144 // wait until LSCP server answers with a multi line answer
145 vector<string> LSCPTest::receiveMultiLineAnswerFromLSCPServer() {
146 string msg = receiveAnswerFromLSCPServer("\n.\r\n");
147 return __ConvertMultiLineMessage(msg);
148 }
149
150 // wait until LSCP server answers with the given \a delimiter token at the end
151 string LSCPTest::receiveAnswerFromLSCPServer(string delimiter) {
152 if (!hServerIn) {
153 cout << "receiveAnswerFromLSCPServer() error: client socket not ready\n" << flush;
154 return "";
155 }
156 string message;
157 char c;
158 while ((c = fgetc(hServerIn)) != EOF) {
159 message += c;
160 string::size_type pos = message.rfind(delimiter); // ouch, but this is only a test case, right? ;)
161 if (pos != string::npos) return message;
162 }
163 cout << "receiveAnswerFromLSCPServer() error: EOF reached\n" << flush;
164 return "";
165 }
166
167
168
169 void LSCPTest::printTestSuiteName() {
170 cout << "\b \nRunning LSCP Tests: " << flush;
171 }
172
173 void LSCPTest::setUp() {
174 }
175
176 void LSCPTest::tearDown() {
177 }
178
179
180
181 // Check if we can launch the LSCP Server (implies that there's no other instance running at the moment).
182 void LSCPTest::testLaunchLSCPServer() {
183 //cout << "testLaunchLSCPServer()\n" << flush;
184 CPPUNIT_ASSERT(launchLSCPServer());
185 }
186
187 // Check if we can connect a client connection to the LSCP server and close that connection without problems.
188 void LSCPTest::testConnectToLSCPServer() {
189 //cout << "testConnectToLSCPServer()\n" << flush;
190 sleep(1); // wait 1s
191 CPPUNIT_ASSERT(connectToLSCPServer());
192 sleep(2); // wait 2s
193 CPPUNIT_ASSERT(closeConnectionToLSCPServer());
194 }
195
196 // Check "ADD CHANNEL" LSCP command.
197 void LSCPTest::test_ADD_CHANNEL() {
198 sleep(1); // wait 1s
199 CPPUNIT_ASSERT(connectToLSCPServer());
200
201 sendCommandToLSCPServer("ADD CHANNEL");
202 CPPUNIT_ASSERT(receiveSingleLineAnswerFromLSCPServer() == "OK[0]");
203
204 sendCommandToLSCPServer("ADD CHANNEL");
205 CPPUNIT_ASSERT(receiveSingleLineAnswerFromLSCPServer() == "OK[1]");
206
207 sendCommandToLSCPServer("ADD CHANNEL");
208 CPPUNIT_ASSERT(receiveSingleLineAnswerFromLSCPServer() == "OK[2]");
209 }
210
211 // Check "GET CHANNELS" LSCP command.
212 void LSCPTest::test_GET_CHANNELS() {
213 sendCommandToLSCPServer("GET CHANNELS");
214 string answer = receiveSingleLineAnswerFromLSCPServer();
215 int initial_channels = atoi(answer.c_str());
216
217 // add sampler channels and check if the count increases
218 for (uint trial = 1; trial <= 3; trial++) {
219 sendCommandToLSCPServer("ADD CHANNEL");
220 answer = receiveSingleLineAnswerFromLSCPServer();
221 sendCommandToLSCPServer("GET CHANNELS");
222 answer = receiveSingleLineAnswerFromLSCPServer();
223 int channels = atoi(answer.c_str());
224 CPPUNIT_ASSERT(channels == initial_channels + trial);
225 }
226 }
227
228 // Check "REMOVE CHANNEL" LSCP command.
229 void LSCPTest::test_REMOVE_CHANNEL() {
230 // how many channels do we have at the moment?
231 sendCommandToLSCPServer("GET CHANNELS");
232 string answer = receiveSingleLineAnswerFromLSCPServer();
233 int initial_channels = atoi(answer.c_str());
234
235 // if there are no sampler channels yet, create some
236 if (!initial_channels) {
237 const uint create_channels = 4;
238 for (uint i = 0; i < create_channels; i++) {
239 sendCommandToLSCPServer("ADD CHANNEL");
240 answer = receiveSingleLineAnswerFromLSCPServer();
241 }
242 initial_channels = create_channels;
243 }
244
245 // now remove the channels until there is no one left and check if we really need 'initial_channels' times to achieve that
246 for (uint channels = initial_channels; channels; channels--) {
247 sendCommandToLSCPServer("LIST CHANNELS");
248 answer = receiveSingleLineAnswerFromLSCPServer();
249 if (answer == "") CPPUNIT_ASSERT(false); // no sampler channel left already? -> failure
250
251 // take the last channel number in the list which we will take to remove that sampler channel
252 string::size_type pos = answer.rfind(",");
253 string channel_to_remove = (pos != string::npos) ? answer.substr(pos + 1, answer.length() - (pos + 1)) /* "m,n,...,t */
254 : answer; /* "k" */
255
256 //cout << " channel_to_remove: \"" << channel_to_remove << "\"\n" << flush;
257
258 // remove that channel
259 sendCommandToLSCPServer("REMOVE CHANNEL " + channel_to_remove);
260 answer = receiveSingleLineAnswerFromLSCPServer();
261 CPPUNIT_ASSERT(answer == "OK");
262 }
263 CPPUNIT_ASSERT(true); // success
264 }
265
266 // Check if we can shutdown the LSCP Server without problems.
267 void LSCPTest::testShutdownLSCPServer() {
268 //cout << "testShutdownLSCPServer()\n" << flush;
269 sleep(2); // wait 2s
270 CPPUNIT_ASSERT(closeConnectionToLSCPServer());
271 sleep(3); // wait 3s
272 CPPUNIT_ASSERT(shutdownLSCPServer());
273 }

  ViewVC Help
Powered by ViewVC