(file) Return to utils.cpp CVS log (file) (dir) Up to [OMI] / omi / unittest

  1 mike  1.1 /*
  2           **==============================================================================
  3           **
  4           ** Open Management Infrastructure (OMI)
  5           **
  6           ** Copyright (c) Microsoft Corporation
  7           ** 
  8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  9           ** use this file except in compliance with the License. You may obtain a copy 
 10           ** of the License at 
 11           **
 12           **     http://www.apache.org/licenses/LICENSE-2.0 
 13           **
 14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
 16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
 17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
 18           **
 19           ** See the Apache 2 License for the specific language governing permissions 
 20           ** and limitations under the License.
 21           **
 22 mike  1.1 **==============================================================================
 23           */
 24           
 25           #include "utils.h"
 26           #include <ut/ut.h>
 27           #include <base/io.h>
 28           #include <base/paths.h>
 29           #include <omiclient/client.h>
 30           #include <iostream>
 31           
 32           #if defined(CONFIG_OS_WINDOWS)
 33           #include <process.h>
 34           #else
 35           #include <unistd.h>
 36           #include <sys/wait.h>
 37           
 38           static pid_t child;
 39           #endif
 40           
 41           using namespace std;
 42           
 43 mike  1.1 #define REQUEST_HEADER_FMT \
 44               "POST /wsman HTTP/1.1\r\n" \
 45               "Content-Length: %d\r\n"\
 46               "Connection: Keep-Alive\r\n"\
 47               "Content-Type: application/soap+xml;charset=UTF-8\r\n"\
 48               "Authorization:    Basic \t \tcm9vdDpPcHNNZ3IyMDA3UjI=\t \r\n"\
 49               "\r\n"
 50           
 51           #define REQUEST_HEADER_FMT_UTF16 \
 52               "POST /wsman HTTP/1.1\r\n" \
 53               "Content-Length: %d\r\n"\
 54               "Connection: Keep-Alive\r\n"\
 55               "Content-Type: application/soap+xml;charset=UTF-16\r\n"\
 56               "Authorization:    Basic \t \tcm9vdDpPcHNNZ3IyMDA3UjI=\t \r\n"\
 57               "\r\n"
 58            
 59           #define REQUEST_HEADER_MAX_SIZE sizeof(REQUEST_HEADER_FMT_UTF16)
 60           
 61           Sock SockConnectLocal(unsigned short port)
 62           {
 63               Sock sock;
 64 mike  1.1     Addr addr;
 65               MI_Result r;
 66           
 67               Sock_Start();
 68           
 69               // Initialize address (connect using loopback).
 70               r = Addr_Init(&addr, "127.0.0.1", port);
 71               UT_ASSERT(r == MI_RESULT_OK);
 72           
 73               // Create client socket.
 74               r = Sock_Create(&sock);
 75               UT_ASSERT(r == MI_RESULT_OK);
 76            
 77               r = Sock_Connect(sock, &addr);
 78               UT_ASSERT(r == MI_RESULT_OK);
 79               return sock;
 80           }
 81           
 82           void SockSendRecvHTTP(
 83               Sock s,
 84               bool useUtf16HeaderAttribute,
 85 mike  1.1     const string& request_body,
 86               string& response_header,
 87               string& response_body)
 88           {
 89               // prepare data to send
 90           
 91               char currentLine[REQUEST_HEADER_MAX_SIZE + 10 /* content length */ ];
 92           
 93               size_t buf_size, sent = 0;
 94               MI_Result r;
 95           
 96               buf_size = (size_t)Snprintf(
 97                   currentLine,
 98                   sizeof(currentLine),
 99                   (useUtf16HeaderAttribute ? REQUEST_HEADER_FMT_UTF16 : REQUEST_HEADER_FMT), 
100                   (int)request_body.size() );
101           
102               r = Sock_Write(s, currentLine, buf_size, &sent);
103               UT_ASSERT (MI_RESULT_OK == r);
104               UT_ASSERT (sent == buf_size);
105           
106 mike  1.1     // body (if present)
107               if (!request_body.empty())
108               {
109                   sent = 0;
110                   r = Sock_Write(s, request_body.c_str(), request_body.size(), &sent);
111           
112                   UT_ASSERT (MI_RESULT_OK == r);
113                   UT_ASSERT (sent == request_body.size());
114               }
115           
116               // read resonse
117           
118               response_header.resize(16 * 1024);
119               size_t read = 0, buf_read = 0;
120               string::size_type pos_crcr;
121           
122               for (;;)
123               {
124                   r = Sock_Read(s, &response_header[0], response_header.size() - buf_read, &read);
125                   UT_ASSERT (MI_RESULT_OK == r);
126           
127 mike  1.1         buf_read += read;
128           
129                   pos_crcr = response_header.find("\r\n\r\n");
130           
131                   if (string::npos != pos_crcr)
132                   {
133                       response_header.resize(buf_read);
134                       break;
135                   }
136               }
137           
138               response_body = response_header.substr(pos_crcr + 4);
139               response_header = response_header.substr(0, pos_crcr);
140           
141               const char CONTENT_LEN[] = "Content-Length:";
142           
143               string::size_type pos_cl = response_header.find(CONTENT_LEN);
144               size_t contentLength = 0;
145           
146               if (string::npos != pos_cl)
147               {
148 mike  1.1         contentLength = atol(response_header.c_str() + pos_cl + sizeof(CONTENT_LEN)-1);
149               }
150               //cout << "cl: " << contentLength << endl;
151               //cout << "resp header: " << response_header << endl << endl << "body: " << response_body << endl;
152           
153               while (response_body.size() < contentLength)
154               {
155                   size_t old_size = response_body.size();
156                   response_body.resize(contentLength);
157           
158                   r = Sock_Read(s, &response_body[0] + old_size, contentLength - old_size, &read);
159                   UT_ASSERT (MI_RESULT_OK == r);
160           
161                   response_body.resize(old_size + read);
162               }
163               //cout << "resp header: " << response_header << endl << endl << "body: " << response_body << endl;
164           }
165           
166           
167           
168           /* launching and terminating the server */
169 mike  1.1 void StartServerAndConnect(
170               bool ignoreAuth,
171               ProtocolCallback callback,
172               Protocol** protocol)
173           {
174               MI_Result r;
175               const char* path = GetPath(ID_SERVERPROGRAM);
176               char http[32];
177               char https[32];
178               string socketFile = GetPath(ID_SOCKETFILE);
179           
180               Snprintf(http, sizeof(http),"%d", ut::getUnittestPortNumberWSMANHTTP());
181               Snprintf(https, sizeof(https),"%d", ut::getUnittestPortNumberWSMANHTTPS());
182           
183               std::string v;
184           
185               if (!ut::testGetAttr("skipServer", v))
186               {
187           
188           #if defined(CONFIG_OS_WINDOWS)
189               MI_UNUSED(ignoreAuth);
190 mike  1.1 
191               intptr_t res = _spawnl(_P_NOWAIT, path, path, "--stopnoop", "--rundir", 
192                   GetPath(ID_PREFIX), 
193                   "--httpport", http,
194                   "--httpsport", https,
195                   "--livetime", "300",
196                   NULL);
197               res = res;
198           #else
199               child = fork();
200               if (!child)
201               {
202                   execl(path, path, "--stopnoop", 
203                       ignoreAuth ? "--ignoreAuthentication" : "--stopnoop", 
204                       "--rundir", GetPath(ID_PREFIX), 
205                       "--httpport", http,
206                       "--httpsport", https,
207                       "--socketfile", socketFile.c_str(),
208                       "--livetime", "300",
209                       NULL );
210                   exit(1); // never get here
211 mike  1.1     }
212           #endif
213               }
214           
215           
216               // wait for server to start
217               // trying to connect in a loop:
218               // since connect may fail quickly if server is not running
219               // keep doing it in  a loop
220               int attempt;
221           
222               for ( attempt = 0; attempt < 400; attempt++ )
223               {
224                   mi::Client cl;
225                   const MI_Uint64 TIMEOUT = 1 * 1000 * 1000;
226           
227           #if defined(CONFIG_OS_WINDOWS)
228                   if (cl.Connect(MI_T("7777"), MI_T("unittest"), MI_T("unittest"), TIMEOUT))
229           #else
230                   if (cl.Connect(socketFile.c_str(), MI_T(USER), MI_T(PASSWORD), TIMEOUT))
231           #endif
232 mike  1.1             break;
233           
234                   ut::sleep_ms(10);
235               }
236           
237               if ( attempt == 400 )
238               {
239                   std::cout << "Warning: unable to connect to the server!\n";
240               }
241               r = Protocol_New_Connector(protocol, 0, socketFile.c_str(), callback, 0,
242                   0, 0, USER, PASSWORD);
243           }
244           
245           
246           
247           void StopServerAndDisconnect(
248               Protocol** protocol)
249           {
250               NoOpReq* rqt;
251               std::string v;
252           
253 mike  1.1     if (ut::testGetAttr("skipServer", v))
254               {
255                   Protocol_Delete(*protocol);
256                   *protocol = 0;
257                   return ;
258               }
259           
260               rqt = NoOpReq_New(0);
261               if (rqt)
262               {
263                   Protocol_Send(*protocol, &rqt->base);
264                   NoOpReq_Release(rqt);
265               }
266               Protocol_Run(*protocol, 10000);
267           
268               Protocol_Delete(*protocol);
269               *protocol = 0;
270           
271           #if !defined(CONFIG_OS_WINDOWS)
272               int attempt = 0;
273               do {
274 mike  1.1         usleep(20000);
275                   attempt++;
276           
277                   if (attempt > 100 )
278                   {
279                       cout << "Warning: unable to stop the server!\n";
280                       break;
281                   }
282               }
283               while( child != waitpid(child, 0, WNOHANG));
284           #endif
285           }

ViewCVS 0.9.2