(file) Return to test_protocol.cpp CVS log (file) (dir) Up to [OMI] / omi / protocol / tests

  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 <vector>
 26           #include <cstdlib>
 27           #include <ut/ut.h>
 28           #include <protocol/protocol.h>
 29           #include <base/time.h>
 30           #include <base/base.h>
 31           #include <base/paths.h>
 32           #include "base/tests/MSFT_AllTypes.h"
 33           
 34           #if defined(CONFIG_POSIX)
 35           # include <unistd.h>
 36           # include <errno.h>
 37           # include <sys/socket.h>
 38           # include <netinet/tcp.h>
 39           # include <netinet/in.h>
 40           # include <sys/time.h>
 41           # include <sys/types.h>
 42           # include <netdb.h>
 43 mike  1.1 # include <fcntl.h>
 44           # include <arpa/inet.h>
 45           # include <signal.h>
 46           #endif
 47           
 48           #define PORT ut::getUnittestPortNumber()
 49           
 50           using namespace std;
 51           using namespace mi;
 52           
 53           static vector<ProtocolEvent> s_events;
 54           
 55           #if defined(_MSC_VER)
 56           #undef BEGIN_EXTERNC
 57           #undef END_EXTERNC
 58           #define BEGIN_EXTERNC
 59           #define END_EXTERNC
 60           #endif
 61           
 62           static void setUp()
 63           {
 64 mike  1.1     s_events.clear();
 65           }
 66           
 67           static void cleanup()
 68           {
 69           }
 70           
 71           BEGIN_EXTERNC
 72           static MI_Boolean _ServerCallback(
 73               Protocol* protocol,
 74               Message* message,
 75               void* data)
 76           {
 77               // memorize request
 78               Message** msgOut = (Message**)data;
 79           
 80               UT_ASSERT( 0 == *msgOut ); // expecting only one message
 81           
 82               *msgOut = message;
 83               Message_AddRef( *msgOut );
 84           
 85 mike  1.1     // send response
 86               NoOpReq* req = (NoOpReq*)message;
 87               NoOpRsp* rsp;
 88           
 89               /* Send NoOp response back */
 90               rsp = NoOpRsp_New(req->base.msgID);
 91               rsp->base.clientID = req->base.clientID;
 92               Protocol_Send(protocol, &rsp->base);
 93               NoOpRsp_Release(rsp);
 94           
 95               return MI_TRUE;
 96           }
 97           END_EXTERNC
 98           
 99           BEGIN_EXTERNC
100           static MI_Boolean _ClientCallback(
101               Protocol* protocol,
102               Message* message,
103               void* data)
104           {
105               protocol = protocol;
106 mike  1.1 
107               Message** msgOut = (Message**)data;
108           
109               UT_ASSERT( 0 == *msgOut ); // expecting only one message
110           
111               *msgOut = message;
112               Message_AddRef( *msgOut );
113           
114               return MI_TRUE;
115           }
116           END_EXTERNC
117           
118           static void TestHappyPass()
119           {
120               /* send noop-rqt and recv noop-rsp */
121               // create 2 protocols - listener and connector
122               Protocol *listener, *connector;
123               Message* recvMessageClient = 0; // response from server
124               Message* recvMessageServer = 0; // req received by server
125           
126               UT_ASSERT( MI_RESULT_OK == Protocol_New_Listener(
127 mike  1.1         &listener, 0, GetPath(ID_SOCKETFILE), _ServerCallback, (void*)&recvMessageServer) );
128           
129               UT_ASSERT(MI_RESULT_OK == Protocol_New_Connector(&connector, 0, 
130                   GetPath(ID_SOCKETFILE), _ClientCallback, (void*)&recvMessageClient, 0, 0, "unittest", "unittest"));
131           
132           
133               // send noop from client
134               NoOpReq* rqt = NoOpReq_New(777);
135               Protocol_Send(connector, &rqt->base);
136               NoOpReq_Release(rqt);
137           
138               for ( int attempt = 0; attempt < 12 && !recvMessageClient; attempt++)
139               {
140                   Protocol_Run(connector, 1000);
141                   Protocol_Run(listener, 1000);
142               }
143           
144               // check messages
145               UT_ASSERT( recvMessageServer );
146               UT_ASSERT( recvMessageServer->tag == NoOpReqTag );
147           
148 mike  1.1     UT_ASSERT( recvMessageClient );
149               UT_ASSERT( recvMessageClient->tag == NoOpRspTag );
150               UT_ASSERT( recvMessageClient->msgID == 777 );
151           
152               // free messages
153               Message_Release(recvMessageServer);
154               Message_Release(recvMessageClient);
155           
156               UT_ASSERT( MI_RESULT_OK == Protocol_Delete(listener) );
157               UT_ASSERT( MI_RESULT_OK == Protocol_Delete(connector) );
158           }
159           
160           BEGIN_EXTERNC
161           static void _TransferMessageUsingProtocol(
162               Message* msg,
163               Message** result,
164               bool listenerUsesExternalSelect = false, 
165               bool connectorUsesExternalSelect = false,
166               Sock* socketPair = 0)
167           {
168               Selector internal_selector;
169 mike  1.1     Selector*   selector = 0;
170               Message* recvMessageClient = 0; // response from server; assigned in _ClientCallback
171           
172               if (listenerUsesExternalSelect || connectorUsesExternalSelect)
173               {
174                   /* Initialize the network */
175                   Sock_Start();
176           
177                   UT_ASSERT(Selector_Init(&internal_selector) == MI_RESULT_OK);
178                   selector = &internal_selector;
179               }
180           
181               /* send message to the server and return received message from server's callback */
182               // create 2 protocols - listener and connector
183               Protocol *listener, *connector;
184           
185               if (0 == socketPair)
186               {
187                   UT_ASSERT( MI_RESULT_OK == Protocol_New_Listener(
188                       &listener, listenerUsesExternalSelect ? selector : 0, GetPath(ID_SOCKETFILE), _ServerCallback, (void*)result) );
189           
190 mike  1.1         UT_ASSERT(MI_RESULT_OK == Protocol_New_Connector(&connector, 
191                       connectorUsesExternalSelect ? selector : 0, GetPath(ID_SOCKETFILE), 
192                       _ClientCallback, (void*)&recvMessageClient, 0, 0, "unittest", "unittest"));
193               }
194               else
195               {
196                   UT_ASSERT( MI_RESULT_OK == Protocol_New_From_Socket(
197                       &listener, 
198                       listenerUsesExternalSelect ? selector : 0, 
199                       socketPair[0], 
200                       MI_FALSE,
201                       _ServerCallback, (void*)result,
202                       0,0) );
203           
204                   UT_ASSERT(MI_RESULT_OK == Protocol_New_From_Socket(
205                       &connector, 
206                       connectorUsesExternalSelect ? selector : 0, 
207                       socketPair[1], 
208                       MI_FALSE,
209                       _ClientCallback, (void*)&recvMessageClient, 0, 0));
210               }
211 mike  1.1 
212               // send noop from client
213               Protocol_Send(connector, msg);
214           
215               for ( int attempt = 0; attempt < 12 && !*result; attempt++)
216               {
217                   Protocol_Run(connector, 1000);
218                   Protocol_Run(listener, 1000);
219               }
220           
221               /* remove all handlers befroe destroying protocols */
222               if (selector)
223                   Selector_RemoveAllHandlers(selector);
224           
225               UT_ASSERT( MI_RESULT_OK == Protocol_Delete(listener) );
226               UT_ASSERT( MI_RESULT_OK == Protocol_Delete(connector) );
227           
228               if (selector)
229               {
230                   Selector_Destroy(selector);
231           
232 mike  1.1         /* Shutdown the network */
233                   Sock_Stop();
234               }
235           
236               if (recvMessageClient)
237                   Message_Release(recvMessageClient);
238           
239           }
240           END_EXTERNC
241           
242           static void TestTransferingEnumerateInstanceRequest()
243           {
244               EnumerateInstancesReq* msg = EnumerateInstancesReq_New( 1444, BinaryProtocolFlag );
245               Message* result = 0;
246           
247               msg->deepInheritance = MI_TRUE;
248               msg->nameSpace = Batch_Strdup2(msg->base.batch, "name_space");
249               msg->className = Batch_Strdup2(msg->base.batch, "class_name");
250           
251               _TransferMessageUsingProtocol( &msg->base, &result );
252           
253 mike  1.1     /* free source message */
254               UT_ASSERT(msg->base.refCounter == 1);
255               EnumerateInstancesReq_Release(msg);
256           
257               /* check received result */
258               UT_ASSERT( result );
259               UT_ASSERT( result->tag == EnumerateInstancesReqTag );
260           
261               {
262                   EnumerateInstancesReq* rsp = (EnumerateInstancesReq*)result;
263                   UT_ASSERT( Zcmp(rsp->nameSpace, MI_T("name_space")) == 0 );
264                   UT_ASSERT( Zcmp(rsp->className, MI_T("class_name")) == 0 );
265                   UT_ASSERT( rsp->deepInheritance );
266               }
267           
268               UT_ASSERT(result->refCounter == 1);
269               Message_Release(result);
270           }
271           
272           static void TestTransferingResult()
273           {
274 mike  1.1     PostResultMsg* msg = PostResultMsg_New( 1444 );
275               Message* result = 0;
276           
277               msg->result = MI_RESULT_NOT_FOUND;
278           
279               _TransferMessageUsingProtocol( &msg->base, &result );
280           
281               /* free source message */
282               UT_ASSERT(msg->base.refCounter == 1);
283               PostResultMsg_Release(msg);
284           
285               /* check received result */
286               UT_ASSERT( result );
287               UT_ASSERT( result->tag == PostResultMsgTag );
288           
289               {
290                   PostResultMsg* rsp = (PostResultMsg*)result;
291                   UT_ASSERT( rsp->result == MI_RESULT_NOT_FOUND);
292               }
293           
294               UT_ASSERT(result->refCounter == 1);
295 mike  1.1     Message_Release(result);
296           }
297           
298           BEGIN_EXTERNC
299           static void _DynamicToStatikInstance(
300               MI_Instance* dynamicInst,
301               Batch* batch,
302               MSFT_AllTypes_Class& inst)
303           {
304               MI_Instance* instOut = 0;
305           
306               /* Allocate the instance for the provider */
307               instOut = (MI_Instance*)Batch_GetClear(batch, 
308                   MSFT_AllTypes_rtti.size);
309           
310               /* Convert instance name to provider's format (borrow storage) */
311               MI_Result r = Instance_InitConvert(
312                   instOut, 
313                   &MSFT_AllTypes_rtti, 
314                   dynamicInst, 
315                   MI_FALSE, 
316 mike  1.1         MI_FALSE,
317                   MI_FALSE,
318                   batch);
319           
320               UT_ASSERT( MI_RESULT_OK == r );
321           
322               inst = MSFT_AllTypes_Class((const MSFT_AllTypes *)instOut, false);
323           }
324           END_EXTERNC
325           
326           static void TestTransferingGetInstanceReqt()
327           {
328               GetInstanceReq* msg = GetInstanceReq_New( 1444, BinaryProtocolFlag );
329               Message* result = 0;
330           
331               msg->nameSpace = Batch_Strdup2(msg->base.batch, "name_space");
332           
333               // instance - reuse cxx sample instance
334               MSFT_AllTypes_Class inst;
335           
336               // note - get-instance transfers keys only
337 mike  1.1     inst.Key_value(8);
338           
339               UT_ASSERT( MI_RESULT_OK == InstanceToBatch(
340                   *((MI_Instance**)&inst), NULL, NULL, msg->base.batch, 
341                       &msg->packedInstanceNamePtr, &msg->packedInstanceNameSize));
342           
343               msg->includeClassOrigin = MI_TRUE;
344           
345               _TransferMessageUsingProtocol( &msg->base, &result );
346           
347               /* free source message */
348               UT_ASSERT(msg->base.refCounter == 1);
349               GetInstanceReq_Release(msg);
350           
351               /* check received result */
352               UT_ASSERT( result );
353               UT_ASSERT( result->tag == GetInstanceReqTag );
354           
355               {
356                   GetInstanceReq* rsp = (GetInstanceReq*)result;
357                   UT_ASSERT( Zcmp(rsp->nameSpace, MI_T("name_space")) == 0 );
358 mike  1.1         UT_ASSERT( rsp->includeClassOrigin );
359           
360                   // instance
361                   UT_ASSERT(rsp->instanceName);
362                   //MSFT_AllTypesClass recv_inst((const MSFT_AllTypes *)rsp->instanceName, false);
363                   MSFT_AllTypes_Class recv_inst;
364                   _DynamicToStatikInstance( rsp->instanceName, rsp->base.batch, recv_inst );
365           
366                   UT_ASSERT(recv_inst.Key_value() == 8);
367               }
368           
369               UT_ASSERT(result->refCounter == 1);
370               Message_Release(result);
371           }
372           
373           static void TestTransferingPostInstance()
374           {
375               PostInstanceMsg* msg = PostInstanceMsg_New( 1444 );
376               Message* result = 0;
377           
378               // instance - reuse cxx sample instance
379 mike  1.1     MSFT_AllTypes_Class inst;
380               MI_ConstString test_string = MI_T("some very very very long string 1111111111111111111111111111111111111111111111111111111111111\
381                   12333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333");
382           
383               inst.Key_value(8);
384               inst.StringValue_value(test_string);
385           
386               UT_ASSERT( MI_RESULT_OK == InstanceToBatch(
387                   *((MI_Instance**)&inst), NULL, NULL, msg->base.batch, 
388                       &msg->packedInstancePtr, &msg->packedInstanceSize));
389           
390               _TransferMessageUsingProtocol( &msg->base, &result );
391           
392               /* free source message */
393               UT_ASSERT(msg->base.refCounter == 1);
394               PostInstanceMsg_Release(msg);
395           
396               /* check received result */
397               UT_ASSERT( result );
398               UT_ASSERT( result->tag == PostInstanceMsgTag );
399           
400 mike  1.1     {
401                   PostInstanceMsg* rsp = (PostInstanceMsg*)result;
402           
403                   // instance
404                   UT_ASSERT(rsp->instance);
405                   //MSFT_AllTypesClass recv_inst((const MSFT_AllTypes *)rsp->instance, false);
406                   MSFT_AllTypes_Class recv_inst;
407                   _DynamicToStatikInstance( rsp->instance, rsp->base.batch, recv_inst );
408           
409                   UT_ASSERT(recv_inst.Key_value() == 8);
410                   UT_ASSERT(recv_inst.StringValue_value() == test_string);
411               }
412           
413               UT_ASSERT(result->refCounter == 1);
414               Message_Release(result);
415           }
416           
417           BEGIN_EXTERNC
418           static void _TestTransferingInvoke(bool listenerUsesExternalSelect, bool connectorUsesExternalSelect, Sock* socketPair)
419           {
420               InvokeReq* msg = InvokeReq_New( 1444, BinaryProtocolFlag );
421 mike  1.1     Message* result = 0;
422           
423               msg->nameSpace = Batch_Strdup2(msg->base.batch, "name_space");
424               msg->function = Batch_Strdup2(msg->base.batch, "function");
425               msg->className = Batch_Strdup2(msg->base.batch, "className");
426           
427               // instance - reuse cxx sample instance
428               MSFT_AllTypes_Class inst;
429               MI_ConstString test_string = MI_T("some very very very long string 1111111111111111111111111111111111111111111111111111111111111\
430                   12333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333");
431           
432               inst.Key_value(8);
433               inst.StringValue_value(test_string);
434           
435               UT_ASSERT( MI_RESULT_OK == InstanceToBatch(
436                   *((MI_Instance**)&inst), NULL, NULL, msg->base.batch, 
437                       &msg->packedInstancePtr, &msg->packedInstanceSize));
438           
439               UT_ASSERT( MI_RESULT_OK == InstanceToBatch(
440                   *((MI_Instance**)&inst), NULL, NULL, msg->base.batch, 
441                       &msg->packedInstanceParamsPtr, &msg->packedInstanceParamsSize));
442 mike  1.1 
443               _TransferMessageUsingProtocol( &msg->base, &result, listenerUsesExternalSelect, connectorUsesExternalSelect, socketPair );
444           
445               /* free source message */
446               UT_ASSERT(msg->base.refCounter == 1);
447               InvokeReq_Release(msg);
448           
449               /* check received result */
450               UT_ASSERT( result );
451               UT_ASSERT( result->tag == InvokeReqTag );
452           
453               {
454                   InvokeReq* rsp = (InvokeReq*)result;
455           
456                   UT_ASSERT( Zcmp(rsp->nameSpace, MI_T("name_space")) == 0 );
457                   UT_ASSERT( Zcmp(rsp->function, MI_T("function")) == 0 );
458                   UT_ASSERT( Zcmp(rsp->className, MI_T("className")) == 0 );
459           
460                   // instance
461                   UT_ASSERT(rsp->instance);
462                   UT_ASSERT(rsp->instanceParams);
463 mike  1.1         MSFT_AllTypes_Class recv_inst, recv_inst_params;
464                   _DynamicToStatikInstance( rsp->instance, rsp->base.batch, recv_inst );
465                   _DynamicToStatikInstance( rsp->instanceParams, rsp->base.batch, recv_inst_params );
466           
467                   UT_ASSERT(recv_inst.Key_value() == 8);
468                   UT_ASSERT(recv_inst.StringValue_value() == test_string);
469           
470                   UT_ASSERT(recv_inst_params.Key_value() == 8);
471                   UT_ASSERT(recv_inst_params.StringValue_value() == test_string);
472               }
473           
474               UT_ASSERT(result->refCounter == 1);
475               Message_Release(result);
476           }
477           END_EXTERNC
478           
479           static void TestTransferingInvoke()
480           {
481               _TestTransferingInvoke(false, false, 0);
482           }
483           
484 mike  1.1 static void TestTransferingInvokeWithExternalSelector()
485           {
486               _TestTransferingInvoke(true, false, 0);
487               _TestTransferingInvoke(false, true, 0);
488               _TestTransferingInvoke(true, true, 0);
489           }
490           
491           BEGIN_EXTERNC
492           static void _ProtocolEventCallback(
493               Protocol* protocol,
494               ProtocolEvent event,
495               void* data)
496           {
497               MI_UNUSED(protocol);
498               MI_UNUSED(data);
499           
500               s_events.push_back(event);
501           }
502           END_EXTERNC
503           
504           static void TestProtocolConnectOK()
505 mike  1.1 {
506               // create 2 protocols - listener and connector
507               Protocol *listener, *connector;
508               Message* recvMessageClient = 0; // response from server
509               Message* recvMessageServer = 0; // req received by server
510           
511               UT_ASSERT( MI_RESULT_OK == Protocol_New_Listener(
512                   &listener, 0, GetPath(ID_SOCKETFILE), _ServerCallback, (void*)&recvMessageServer) );
513           
514               UT_ASSERT(MI_RESULT_OK == Protocol_New_Connector(&connector, 
515                   0, GetPath(ID_SOCKETFILE), 
516                   _ClientCallback, (void*)&recvMessageClient, _ProtocolEventCallback, 0, "unittest", "unittest"));
517           
518               // send noop from client
519               NoOpReq* rqt = NoOpReq_New(777);
520               Protocol_Send(connector, &rqt->base);
521               NoOpReq_Release(rqt);
522           
523               for ( int attempt = 0; attempt < 100 && !recvMessageClient; attempt++)
524               {
525                   Protocol_Run(connector, 1000);
526 mike  1.1         Protocol_Run(listener, 1000);
527               }
528           
529               // verify connect event
530               UT_ASSERT(s_events.size() == 1);
531               UT_ASSERT(s_events[0] == PROTOCOLEVENT_CONNECT);
532           
533           
534               UT_ASSERT( MI_RESULT_OK == Protocol_Delete(listener) );
535               s_events.clear();
536           
537               // verify disconnect event
538               for ( int attempt = 0; attempt < 2 && s_events.empty(); attempt++)
539               {
540                   Protocol_Run(connector, 1000);
541               }
542           
543               UT_ASSERT(s_events.size() == 1);
544               UT_ASSERT(s_events[0] == PROTOCOLEVENT_DISCONNECT);
545           
546               UT_ASSERT( MI_RESULT_OK == Protocol_Delete(connector) );
547 mike  1.1 
548               // check messages
549               UT_ASSERT( recvMessageServer );
550               UT_ASSERT( recvMessageServer->tag == NoOpReqTag );
551           
552               UT_ASSERT( recvMessageClient );
553               UT_ASSERT( recvMessageClient->tag == NoOpRspTag );
554               UT_ASSERT( recvMessageClient->msgID == 777 );
555           
556               // free messages
557               Message_Release(recvMessageServer);
558               Message_Release(recvMessageClient);
559           
560           }
561           
562           static void TestProtocolConnectFailed()
563           {
564               // create only connector - should fail to connect
565               Protocol *connector;
566           
567               MI_Result r = Protocol_New_Connector(&connector, 
568 mike  1.1         0, GetPath(ID_SOCKETFILE), 
569                   _ClientCallback, 0, _ProtocolEventCallback, 0, "unittest", "unittest");
570           
571               /* some platforms return 'failed' from connect even with non-blocking sockets */
572               if (MI_RESULT_FAILED == r)
573                   return;
574           
575               UT_ASSERT(MI_RESULT_OK == r);
576           
577               // send noop from client
578               NoOpReq* rqt = NoOpReq_New(777);
579               Protocol_Send(connector, &rqt->base);
580               NoOpReq_Release(rqt);
581           
582               for ( int attempt = 0; attempt < 10000 && s_events.empty(); attempt++)
583               {
584                   Protocol_Run(connector, 1000);
585               }
586           
587               // verify connect-failed event
588               UT_ASSERT(s_events.size() == 1);
589 mike  1.1     UT_ASSERT(s_events[0] == PROTOCOLEVENT_CONNECT_FAILED);
590           
591               UT_ASSERT( MI_RESULT_OK == Protocol_Delete(connector) );
592           }
593           
594           #ifdef CONFIG_POSIX
595           static void TestFromSocket()
596           {
597               Sock s[2];
598           
599               UT_ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, s));
600               UT_ASSERT( MI_RESULT_OK == Sock_SetBlocking(s[0], MI_FALSE));
601               UT_ASSERT( MI_RESULT_OK == Sock_SetBlocking(s[1], MI_FALSE));
602           
603               _TestTransferingInvoke(true, true, s);
604           }
605           #endif
606           
607           static void RunTests()
608           {
609           #if defined(CONFIG_POSIX)
610 mike  1.1     /* Disable Auth for unit-tests */
611               IgnoreAuthCalls(1);
612           #endif
613           
614               UT_TEST(TestHappyPass);
615               UT_TEST(TestTransferingEnumerateInstanceRequest);
616               UT_TEST(TestTransferingResult);
617               UT_TEST(TestTransferingGetInstanceReqt);
618               UT_TEST(TestTransferingPostInstance);
619               UT_TEST(TestTransferingInvokeWithExternalSelector);
620               UT_TEST(TestTransferingInvoke);
621           
622               // Test protocol events
623               UT_TEST(TestProtocolConnectFailed);
624               UT_TEST(TestProtocolConnectOK);
625           
626           #ifdef CONFIG_POSIX
627               UT_TEST(TestFromSocket);
628           
629           #endif
630           }
631 mike  1.1 
632           UT_ENTRY_POINT(RunTests);

ViewCVS 0.9.2