1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 #include <Ice/Ice.h> 6 #include <TestHelper.h> 7 #include <Test.h> 8 9 using namespace std; 10 11 static string testString = "This is a test string"; 12 13 #ifndef ICE_CPP11_MAPPING 14 class Cookie : public Ice::LocalObject 15 { 16 public: 17 18 string getString() 19 { 20 return testString; 21 } 22 }; 23 typedef IceUtil::Handle<Cookie> CookiePtr; 24 25 class CallbackBase : public IceUtil::Monitor<IceUtil::Mutex> 26 { 27 public: 28 29 CallbackBase() : 30 _called(false) 31 { 32 } 33 34 virtual ~CallbackBase() 35 { 36 } 37 38 void check() 39 { 40 IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); 41 while(!_called) 42 { 43 wait(); 44 } 45 _called = false; 46 } 47 48 protected: 49 50 void called() 51 { 52 IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); 53 assert(!_called); 54 _called = true; 55 notify(); 56 } 57 58 private: 59 60 bool _called; 61 }; 62 63 class Callback : public IceUtil::Shared, public CallbackBase 64 { 65 public: 66 67 Callback(const Ice::CommunicatorPtr& communicator, bool useCookie) : 68 _communicator(communicator), 69 _useCookie(useCookie) 70 { 71 } 72 73 void opString(const Ice::AsyncResultPtr& result) 74 { 75 string cmp = testString; 76 if(_useCookie) 77 { 78 CookiePtr cookie = CookiePtr::dynamicCast(result->getCookie()); 79 cmp = cookie->getString(); 80 } 81 82 Ice::ByteSeq outParams; 83 if(result->getProxy()->end_ice_invoke(outParams, result)) 84 { 85 Ice::InputStream in(_communicator, result->getProxy()->ice_getEncodingVersion(), outParams); 86 in.startEncapsulation(); 87 string s; 88 in.read(s); 89 test(s == cmp); 90 in.read(s); 91 test(s == cmp); 92 in.endEncapsulation(); 93 called(); 94 } 95 else 96 { 97 test(false); 98 } 99 } 100 101 void opException(const Ice::AsyncResultPtr& result) 102 { 103 if(_useCookie) 104 { 105 CookiePtr cookie = CookiePtr::dynamicCast(result->getCookie()); 106 test(cookie->getString() == testString); 107 } 108 109 Ice::ByteSeq outParams; 110 if(result->getProxy()->end_ice_invoke(outParams, result)) 111 { 112 test(false); 113 } 114 else 115 { 116 Ice::InputStream in(_communicator, result->getProxy()->ice_getEncodingVersion(), outParams); 117 in.startEncapsulation(); 118 try 119 { 120 in.throwException(); 121 } 122 catch(const Test::MyException&) 123 { 124 in.endEncapsulation(); 125 called(); 126 } 127 catch(...) 128 { 129 test(false); 130 } 131 } 132 } 133 134 void opStringNC(bool ok, const Ice::ByteSeq& outParams) 135 { 136 if(ok) 137 { 138 Ice::InputStream in(_communicator, outParams); 139 in.startEncapsulation(); 140 string s; 141 in.read(s); 142 test(s == testString); 143 in.read(s); 144 test(s == testString); 145 in.endEncapsulation(); 146 called(); 147 } 148 else 149 { 150 test(false); 151 } 152 } 153 154 void opStringPairNC(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& outParams) 155 { 156 if(ok) 157 { 158 Ice::InputStream in(_communicator, outParams); 159 in.startEncapsulation(); 160 string s; 161 in.read(s); 162 test(s == testString); 163 in.read(s); 164 test(s == testString); 165 in.endEncapsulation(); 166 called(); 167 } 168 else 169 { 170 test(false); 171 } 172 } 173 174 void opStringWC(bool ok, const Ice::ByteSeq& outParams, const CookiePtr& cookie) 175 { 176 if(ok) 177 { 178 Ice::InputStream in(_communicator, outParams); 179 in.startEncapsulation(); 180 string s; 181 in.read(s); 182 test(s == cookie->getString()); 183 in.read(s); 184 test(s == cookie->getString()); 185 in.endEncapsulation(); 186 called(); 187 } 188 else 189 { 190 test(false); 191 } 192 } 193 194 void opExceptionNC(bool ok, const Ice::ByteSeq& outParams) 195 { 196 if(ok) 197 { 198 test(false); 199 } 200 else 201 { 202 Ice::InputStream in(_communicator, outParams); 203 in.startEncapsulation(); 204 try 205 { 206 in.throwException(); 207 } 208 catch(const Test::MyException&) 209 { 210 in.endEncapsulation(); 211 called(); 212 } 213 catch(...) 214 { 215 test(false); 216 } 217 } 218 } 219 220 void opExceptionPairNC(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& outParams) 221 { 222 if(ok) 223 { 224 test(false); 225 } 226 else 227 { 228 Ice::InputStream in(_communicator, outParams); 229 in.startEncapsulation(); 230 try 231 { 232 in.throwException(); 233 } 234 catch(const Test::MyException&) 235 { 236 in.endEncapsulation(); 237 called(); 238 } 239 catch(...) 240 { 241 test(false); 242 } 243 } 244 } 245 246 void opExceptionWC(bool ok, const Ice::ByteSeq& outParams, const CookiePtr& cookie) 247 { 248 test(cookie->getString() == testString); 249 if(ok) 250 { 251 test(false); 252 } 253 else 254 { 255 Ice::InputStream in(_communicator, outParams); 256 in.startEncapsulation(); 257 try 258 { 259 in.throwException(); 260 } 261 catch(const Test::MyException&) 262 { 263 in.endEncapsulation(); 264 called(); 265 } 266 catch(...) 267 { 268 test(false); 269 } 270 } 271 } 272 273 private: 274 275 Ice::CommunicatorPtr _communicator; 276 bool _useCookie; 277 }; 278 typedef IceUtil::Handle<Callback> CallbackPtr; 279 #endif 280 281 Test::MyClassPrxPtr 282 allTests(Test::TestHelper* helper) 283 { 284 Ice::CommunicatorPtr communicator = helper->communicator(); 285 string ref = "test:" + helper->getTestEndpoint(); 286 Ice::ObjectPrxPtr base = communicator->stringToProxy(ref); 287 test(base); 288 289 Test::MyClassPrxPtr cl = ICE_CHECKED_CAST(Test::MyClassPrx, base); 290 test(cl); 291 292 Test::MyClassPrxPtr oneway = cl->ice_oneway(); 293 Test::MyClassPrxPtr batchOneway = cl->ice_batchOneway(); 294 295 cout << "testing ice_invoke... " << flush; 296 297 { 298 Ice::ByteSeq inEncaps, outEncaps; 299 if(!oneway->ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, outEncaps)) 300 { 301 test(false); 302 } 303 304 test(batchOneway->ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, outEncaps)); 305 test(batchOneway->ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, outEncaps)); 306 test(batchOneway->ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, outEncaps)); 307 test(batchOneway->ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, outEncaps)); 308 batchOneway->ice_flushBatchRequests(); 309 310 Ice::OutputStream out(communicator); 311 out.startEncapsulation(); 312 out.write(testString); 313 out.endEncapsulation(); 314 out.finished(inEncaps); 315 316 // ice_invoke 317 if(cl->ice_invoke("opString", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, outEncaps)) 318 { 319 Ice::InputStream in(communicator, out.getEncoding(), outEncaps); 320 in.startEncapsulation(); 321 string s; 322 in.read(s); 323 test(s == testString); 324 in.read(s); 325 test(s == testString); 326 in.endEncapsulation(); 327 } 328 else 329 { 330 test(false); 331 } 332 333 // ice_invoke with array mapping 334 pair<const ::Ice::Byte*, const ::Ice::Byte*> inPair(&inEncaps[0], &inEncaps[0] + inEncaps.size()); 335 if(cl->ice_invoke("opString", Ice::ICE_ENUM(OperationMode, Normal), inPair, outEncaps)) 336 { 337 Ice::InputStream in(communicator, out.getEncoding(), outEncaps); 338 in.startEncapsulation(); 339 string s; 340 in.read(s); 341 test(s == testString); 342 in.read(s); 343 test(s == testString); 344 in.endEncapsulation(); 345 } 346 else 347 { 348 test(false); 349 } 350 } 351 352 for(int i = 0; i < 2; ++i) 353 { 354 Ice::ByteSeq inEncaps, outEncaps; 355 Ice::Context ctx; 356 if(i == 1) 357 { 358 ctx["raise"] = ""; 359 } 360 if(cl->ice_invoke("opException", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, outEncaps, ctx)) 361 { 362 test(false); 363 } 364 else 365 { 366 Ice::InputStream in(communicator, cl->ice_getEncodingVersion(), outEncaps); 367 in.startEncapsulation(); 368 try 369 { 370 in.throwException(); 371 } 372 catch(const Test::MyException&) 373 { 374 } 375 catch(...) 376 { 377 test(false); 378 } 379 in.endEncapsulation(); 380 } 381 } 382 383 cout << "ok" << endl; 384 385 cout << "testing asynchronous ice_invoke... " << flush; 386 #ifdef ICE_CPP11_MAPPING 387 388 { 389 Ice::ByteSeq inEncaps; 390 batchOneway->ice_invokeAsync("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps, 391 [](bool, const vector<Ice::Byte>) 392 { 393 test(false); 394 }, 395 [](exception_ptr) 396 { 397 test(false); 398 }, 399 [](bool) 400 { 401 test(false); 402 }); 403 batchOneway->ice_flushBatchRequests(); 404 } 405 // 406 // repeat with the future API. 407 // 408 { 409 Ice::ByteSeq inEncaps; 410 test(batchOneway->ice_invokeAsync("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); 411 test(batchOneway->ice_invokeAsync("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); 412 test(batchOneway->ice_invokeAsync("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); 413 test(batchOneway->ice_invokeAsync("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps).get().returnValue); 414 batchOneway->ice_flushBatchRequests(); 415 } 416 417 { 418 promise<bool> completed; 419 Ice::ByteSeq inEncaps, outEncaps; 420 oneway->ice_invokeAsync( 421 "opOneway", 422 Ice::OperationMode::Normal, 423 inEncaps, 424 nullptr, 425 [&](exception_ptr ex) 426 { 427 completed.set_exception(ex); 428 }, 429 [&](bool) 430 { 431 completed.set_value(true); 432 }); 433 434 test(completed.get_future().get()); 435 } 436 437 // 438 // repeat with the future API. 439 // 440 441 { 442 Ice::ByteSeq inEncaps, outEncaps; 443 auto completed = oneway->ice_invokeAsync("opOneway", Ice::OperationMode::Normal, inEncaps); 444 test(completed.get().returnValue); 445 } 446 447 { 448 promise<bool> completed; 449 Ice::ByteSeq inEncaps, outEncaps; 450 Ice::OutputStream out(communicator); 451 out.startEncapsulation(); 452 out.write(testString); 453 out.endEncapsulation(); 454 out.finished(inEncaps); 455 456 cl->ice_invokeAsync("opString", Ice::OperationMode::Normal, inEncaps, 457 [&](bool ok, vector<Ice::Byte> outParams) 458 { 459 outEncaps = move(outParams); 460 completed.set_value(ok); 461 }, 462 [&](exception_ptr ex) 463 { 464 completed.set_exception(ex); 465 }); 466 test(completed.get_future().get()); 467 468 Ice::InputStream in(communicator, outEncaps); 469 in.startEncapsulation(); 470 string s; 471 in.read(s); 472 test(s == testString); 473 in.read(s); 474 test(s == testString); 475 in.endEncapsulation(); 476 } 477 // 478 // repeat with the future API. 479 // 480 { 481 Ice::ByteSeq inEncaps, outEncaps; 482 Ice::OutputStream out(communicator); 483 out.startEncapsulation(); 484 out.write(testString); 485 out.endEncapsulation(); 486 out.finished(inEncaps); 487 488 auto result = cl->ice_invokeAsync("opString", Ice::OperationMode::Normal, inEncaps).get(); 489 test(result.returnValue); 490 491 Ice::InputStream in(communicator, result.outParams); 492 in.startEncapsulation(); 493 string s; 494 in.read(s); 495 test(s == testString); 496 in.read(s); 497 test(s == testString); 498 in.endEncapsulation(); 499 } 500 501 { 502 promise<bool> completed; 503 promise<void> sent; 504 Ice::ByteSeq inEncaps, outEncaps; 505 Ice::OutputStream out(communicator); 506 out.startEncapsulation(); 507 out.write(testString); 508 out.endEncapsulation(); 509 out.finished(inEncaps); 510 511 auto inPair = make_pair(inEncaps.data(), inEncaps.data() + inEncaps.size()); 512 513 cl->ice_invokeAsync("opString", Ice::OperationMode::Normal, inPair, 514 [&](bool ok, pair<const Ice::Byte*, const Ice::Byte*> outParams) 515 { 516 vector<Ice::Byte>(outParams.first, outParams.second).swap(outEncaps); 517 completed.set_value(ok); 518 }, 519 [&](exception_ptr ex) 520 { 521 completed.set_exception(ex); 522 }, 523 [&](bool) 524 { 525 sent.set_value(); 526 }); 527 sent.get_future().get(); // Ensure sent callback was called 528 test(completed.get_future().get()); 529 530 Ice::InputStream in(communicator, outEncaps); 531 in.startEncapsulation(); 532 string s; 533 in.read(s); 534 test(s == testString); 535 in.read(s); 536 test(s == testString); 537 in.endEncapsulation(); 538 } 539 // 540 // repeat with the future API. 541 // 542 543 { 544 Ice::ByteSeq inEncaps, outEncaps; 545 Ice::OutputStream out(communicator); 546 out.startEncapsulation(); 547 out.write(testString); 548 out.endEncapsulation(); 549 out.finished(inEncaps); 550 551 auto inPair = make_pair(inEncaps.data(), inEncaps.data() + inEncaps.size()); 552 553 auto result = cl->ice_invokeAsync("opString", Ice::OperationMode::Normal, inPair).get(); 554 test(result.returnValue); 555 556 Ice::InputStream in(communicator, result.outParams); 557 in.startEncapsulation(); 558 string s; 559 in.read(s); 560 test(s == testString); 561 in.read(s); 562 test(s == testString); 563 in.endEncapsulation(); 564 } 565 566 { 567 promise<bool> completed; 568 promise<void> sent; 569 Ice::ByteSeq inEncaps, outEncaps; 570 571 cl->ice_invokeAsync("opException", Ice::OperationMode::Normal, inEncaps, 572 [&](bool ok, vector<Ice::Byte> outParams) 573 { 574 outEncaps = move(outParams); 575 completed.set_value(ok); 576 }, 577 [&](exception_ptr ex) 578 { 579 completed.set_exception(ex); 580 }, 581 [&](bool) 582 { 583 sent.set_value(); 584 }); 585 sent.get_future().get(); // Ensure sent callback was called 586 test(!completed.get_future().get()); 587 588 Ice::InputStream in(communicator, outEncaps); 589 in.startEncapsulation(); 590 try 591 { 592 in.throwException(); 593 test(false); 594 } 595 catch(const Test::MyException&) 596 { 597 } 598 catch(...) 599 { 600 test(false); 601 } 602 } 603 // 604 // repeat with the future API. 605 // 606 { 607 Ice::ByteSeq inEncaps; 608 auto result = cl->ice_invokeAsync("opException", Ice::OperationMode::Normal, inEncaps).get(); 609 test(!result.returnValue); 610 611 Ice::InputStream in(communicator, result.outParams); 612 in.startEncapsulation(); 613 try 614 { 615 in.throwException(); 616 test(false); 617 } 618 catch(const Test::MyException&) 619 { 620 } 621 catch(...) 622 { 623 test(false); 624 } 625 } 626 627 #else 628 void (::Callback::*nullEx)(const Ice::Exception&) = 0; 629 void (::Callback::*nullExWC)(const Ice::Exception&, const CookiePtr&) = 0; 630 631 { 632 Ice::ByteSeq inEncaps, outEncaps; 633 test(batchOneway->end_ice_invoke(outEncaps, batchOneway->begin_ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps))); 634 test(batchOneway->end_ice_invoke(outEncaps, batchOneway->begin_ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps))); 635 test(batchOneway->end_ice_invoke(outEncaps, batchOneway->begin_ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps))); 636 test(batchOneway->end_ice_invoke(outEncaps, batchOneway->begin_ice_invoke("opOneway", Ice::ICE_ENUM(OperationMode, Normal), inEncaps))); 637 batchOneway->ice_flushBatchRequests(); 638 } 639 640 { 641 CookiePtr cookie = new Cookie(); 642 643 Ice::ByteSeq inEncaps, outEncaps; 644 Ice::AsyncResultPtr result = oneway->begin_ice_invoke("opOneway", Ice::Normal, inEncaps); 645 if(!oneway->end_ice_invoke(outEncaps, result)) 646 { 647 test(false); 648 } 649 650 Ice::OutputStream out(communicator); 651 out.startEncapsulation(); 652 out.write(testString); 653 out.endEncapsulation(); 654 out.finished(inEncaps); 655 656 // begin_ice_invoke with no callback 657 result = cl->begin_ice_invoke("opString", Ice::Normal, inEncaps); 658 if(cl->end_ice_invoke(outEncaps, result)) 659 { 660 Ice::InputStream in(communicator, out.getEncoding(), outEncaps); 661 in.startEncapsulation(); 662 string s; 663 in.read(s); 664 test(s == testString); 665 in.read(s); 666 test(s == testString); 667 in.endEncapsulation(); 668 } 669 else 670 { 671 test(false); 672 } 673 674 // begin_ice_invoke with no callback and array mapping 675 pair<const ::Ice::Byte*, const ::Ice::Byte*> inPair(&inEncaps[0], &inEncaps[0] + inEncaps.size()); 676 result = cl->begin_ice_invoke("opString", Ice::Normal, inPair); 677 if(cl->end_ice_invoke(outEncaps, result)) 678 { 679 Ice::InputStream in(communicator, out.getEncoding(), outEncaps); 680 in.startEncapsulation(); 681 string s; 682 in.read(s); 683 test(s == testString); 684 in.read(s); 685 test(s == testString); 686 in.endEncapsulation(); 687 } 688 else 689 { 690 test(false); 691 } 692 693 // begin_ice_invoke with Callback 694 ::CallbackPtr cb = new ::Callback(communicator, false); 695 cl->begin_ice_invoke("opString", Ice::Normal, inEncaps, Ice::newCallback(cb, &Callback::opString)); 696 cb->check(); 697 698 // begin_ice_invoke with Callback and Cookie 699 cb = new ::Callback(communicator, true); 700 cl->begin_ice_invoke("opString", Ice::Normal, inEncaps, Ice::newCallback(cb, &Callback::opString), cookie); 701 cb->check(); 702 703 // begin_ice_invoke with Callback_Object_ice_invoke 704 cb = new ::Callback(communicator, false); 705 Ice::Callback_Object_ice_invokePtr d = Ice::newCallback_Object_ice_invoke(cb, &Callback::opStringNC, nullEx); 706 cl->begin_ice_invoke("opString", Ice::Normal, inEncaps, d); 707 cb->check(); 708 709 // begin_ice_invoke with Callback_Object_ice_invoke with Cookie 710 cb = new ::Callback(communicator, false); 711 d = Ice::newCallback_Object_ice_invoke(cb, &Callback::opStringWC, nullExWC); 712 cl->begin_ice_invoke("opString", Ice::Normal, inEncaps, d, cookie); 713 cb->check(); 714 715 // begin_ice_invoke with Callback_Object_ice_invoke and array mapping 716 cb = new ::Callback(communicator, false); 717 d = Ice::newCallback_Object_ice_invoke(cb, &Callback::opStringNC, nullEx); 718 cl->begin_ice_invoke("opString", Ice::Normal, inPair, d); 719 cb->check(); 720 721 // begin_ice_invoke with Callback_Object_ice_invoke and array mapping with Cookie 722 cb = new ::Callback(communicator, false); 723 d = Ice::newCallback_Object_ice_invoke(cb, &Callback::opStringWC, nullExWC); 724 cl->begin_ice_invoke("opString", Ice::Normal, inPair, d, cookie); 725 cb->check(); 726 } 727 728 { 729 CookiePtr cookie = new Cookie(); 730 Ice::ByteSeq inEncaps, outEncaps; 731 732 // begin_ice_invoke with no callback 733 Ice::AsyncResultPtr result = cl->begin_ice_invoke("opException", Ice::Normal, inEncaps); 734 if(cl->end_ice_invoke(outEncaps, result)) 735 { 736 test(false); 737 } 738 else 739 { 740 Ice::InputStream in(communicator, cl->ice_getEncodingVersion(), outEncaps); 741 in.startEncapsulation(); 742 try 743 { 744 in.throwException(); 745 } 746 catch(const Test::MyException&) 747 { 748 } 749 catch(...) 750 { 751 test(false); 752 } 753 in.endEncapsulation(); 754 } 755 756 // begin_ice_invoke with Callback 757 ::CallbackPtr cb = new ::Callback(communicator, false); 758 cl->begin_ice_invoke("opException", Ice::Normal, inEncaps, Ice::newCallback(cb, &Callback::opException)); 759 cb->check(); 760 761 // begin_ice_invoke with Callback and Cookie 762 cb = new ::Callback(communicator, true); 763 cl->begin_ice_invoke("opException", Ice::Normal, inEncaps, Ice::newCallback(cb, &Callback::opException), 764 cookie); 765 cb->check(); 766 767 // begin_ice_invoke with Callback_Object_ice_invoke 768 cb = new ::Callback(communicator, false); 769 Ice::Callback_Object_ice_invokePtr d = Ice::newCallback_Object_ice_invoke(cb, &Callback::opExceptionNC, nullEx); 770 cl->begin_ice_invoke("opException", Ice::Normal, inEncaps, d); 771 cb->check(); 772 773 // begin_ice_invoke with Callback_Object_ice_invoke with Cookie 774 cb = new ::Callback(communicator, false); 775 d = Ice::newCallback_Object_ice_invoke(cb, &Callback::opExceptionWC, nullExWC); 776 cl->begin_ice_invoke("opException", Ice::Normal, inEncaps, d, cookie); 777 cb->check(); 778 } 779 #endif 780 cout << "ok" << endl; 781 return cl; 782 } 783