generate_cpp_unittest.cpp revision 8993cb5f297f9e329470d75f02a7b3e3a4bc64a5
1/* 2 * Copyright (C) 2015, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <string> 18 19#include <gtest/gtest.h> 20 21#include "aidl.h" 22#include "aidl_language.h" 23#include "ast_cpp.h" 24#include "code_writer.h" 25#include "generate_cpp.h" 26#include "tests/fake_io_delegate.h" 27#include "tests/test_util.h" 28#include "type_cpp.h" 29 30using android::aidl::test::FakeIoDelegate; 31using std::string; 32using std::unique_ptr; 33 34namespace android { 35namespace aidl { 36namespace cpp { 37namespace { 38 39const string kPrimitiveInterfaceAIDL = 40R"( 41package android.os; 42 43interface IPingResponder { 44 int Ping(String token); 45})"; 46 47const char kExpectedPrimitiveClientSourceOutput[] = 48R"(#include <android/os/BpPingResponder.h> 49#include <binder/Parcel.h> 50 51namespace android { 52 53namespace os { 54 55BpPingResponder::BpPingResponder(const android::sp<android::IBinder>& impl) 56 : BpInterface<IPingResponder>(impl){ 57} 58 59android::status_t BpPingResponder::Ping(android::String16 token, int32_t* _aidl_return) { 60android::Parcel data; 61android::Parcel reply; 62android::status_t status; 63status = data.writeInterfaceToken(getInterfaceDescriptor()); 64if (((status) != (android::OK))) { 65return status; 66} 67status = data.writeString16(token); 68if (((status) != (android::OK))) { 69return status; 70} 71status = remote()->transact(IPingResponder::PING, data, &reply); 72if (((status) != (android::OK))) { 73return status; 74} 75if (reply.readExceptionCode()) { 76status = android::FAILED_TRANSACTION; 77return status; 78} 79status = reply.readInt32(_aidl_return); 80if (((status) != (android::OK))) { 81return status; 82} 83return status; 84} 85 86} // namespace os 87 88} // namespace android 89)"; 90 91const char kExpectedPrimitiveServerHeaderOutput[] = 92R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_ 93#define AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_ 94 95#include <binder/IInterface.h> 96#include <android/os/IPingResponder.h> 97 98namespace android { 99 100namespace os { 101 102class BnPingResponder : public android::BnInterface<IPingResponder> { 103public: 104android::status_t onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags = 0) override; 105}; // class BnPingResponder 106 107} // namespace os 108 109} // namespace android 110 111#endif // AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_)"; 112 113const char kExpectedPrimitiveServerSourceOutput[] = 114R"(#include <android/os/BnPingResponder.h> 115#include <binder/Parcel.h> 116 117namespace android { 118 119namespace os { 120 121android::status_t BnPingResponder::onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags) { 122android::status_t status; 123switch (code) { 124case Call::PING: 125{ 126android::String16 in_token; 127int32_t _aidl_return; 128if ((!data.checkInterface(this))) { 129status = android::BAD_TYPE; 130break; 131} 132status = data.readString16(&in_token); 133if (((status) != (android::OK))) { 134break; 135} 136status = Ping(in_token, &_aidl_return); 137if (((status) != (android::OK))) { 138break; 139} 140status = reply->writeNoException(); 141if (((status) != (android::OK))) { 142break; 143} 144status = reply->writeInt32(_aidl_return); 145if (((status) != (android::OK))) { 146break; 147} 148} 149break; 150default: 151{ 152status = android::BBinder::onTransact(code, data, reply, flags); 153} 154break; 155} 156return status; 157} 158 159} // namespace os 160 161} // namespace android 162)"; 163 164const char kExpectedPrimitiveClientHeaderOutput[] = 165R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_ 166#define AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_ 167 168#include <binder/IBinder.h> 169#include <binder/IInterface.h> 170#include <utils/Errors.h> 171#include <android/os/IPingResponder.h> 172 173namespace android { 174 175namespace os { 176 177class BpPingResponder : public android::BpInterface<IPingResponder> { 178public: 179explicit BpPingResponder(const android::sp<android::IBinder>& impl); 180virtual ~BpPingResponder() = default; 181android::status_t Ping(android::String16 token, int32_t* _aidl_return) override; 182}; // class BpPingResponder 183 184} // namespace os 185 186} // namespace android 187 188#endif // AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_)"; 189 190const char kExpectedPrimitiveInterfaceHeaderOutput[] = 191R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_ 192#define AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_ 193 194#include <binder/IBinder.h> 195#include <binder/IInterface.h> 196#include <cstdint> 197#include <utils/String16.h> 198 199namespace android { 200 201namespace os { 202 203class IPingResponder : public android::IInterface { 204public: 205DECLARE_META_INTERFACE(PingResponder); 206virtual android::status_t Ping(android::String16 token, int32_t* _aidl_return) = 0; 207enum Call { 208 PING = android::IBinder::FIRST_CALL_TRANSACTION + 0, 209}; 210}; // class IPingResponder 211 212} // namespace os 213 214} // namespace android 215 216#endif // AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_)"; 217 218const char kExpectedPrimitiveInterfaceSourceOutput[] = 219R"(#include <android/os/IPingResponder.h> 220#include <android/os/BpPingResponder.h> 221 222namespace android { 223 224namespace os { 225 226IMPLEMENT_META_INTERFACE(PingResponder, "android.os.IPingResponder"); 227 228} // namespace os 229 230} // namespace android 231)"; 232 233const string kComplexTypeInterfaceAIDL = 234R"(package android.os; 235interface IComplexTypeInterface { 236 int Send(in int[] token, out boolean[] item); 237 oneway void Piff(int times); 238})"; 239 240const char kExpectedComplexTypeClientHeaderOutput[] = 241R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_ 242#define AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_ 243 244#include <binder/IBinder.h> 245#include <binder/IInterface.h> 246#include <utils/Errors.h> 247#include <android/os/IComplexTypeInterface.h> 248 249namespace android { 250 251namespace os { 252 253class BpComplexTypeInterface : public android::BpInterface<IComplexTypeInterface> { 254public: 255explicit BpComplexTypeInterface(const android::sp<android::IBinder>& impl); 256virtual ~BpComplexTypeInterface() = default; 257android::status_t Send(const std::vector<int32_t>& token, std::vector<bool>* item, int32_t* _aidl_return) override; 258android::status_t Piff(int32_t times) override; 259}; // class BpComplexTypeInterface 260 261} // namespace os 262 263} // namespace android 264 265#endif // AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_)"; 266 267const char kExpectedComplexTypeClientSourceOutput[] = 268R"(#include <android/os/BpComplexTypeInterface.h> 269#include <binder/Parcel.h> 270 271namespace android { 272 273namespace os { 274 275BpComplexTypeInterface::BpComplexTypeInterface(const android::sp<android::IBinder>& impl) 276 : BpInterface<IPingResponder>(impl){ 277} 278 279android::status_t BpComplexTypeInterface::Send(const std::vector<int32_t>& token, std::vector<bool>* item, int32_t* _aidl_return) { 280android::Parcel data; 281android::Parcel reply; 282android::status_t status; 283status = data.writeInterfaceToken(getInterfaceDescriptor()); 284if (((status) != (android::OK))) { 285return status; 286} 287status = data.writeInt32Vector(token); 288if (((status) != (android::OK))) { 289return status; 290} 291status = remote()->transact(IComplexTypeInterface::SEND, data, &reply); 292if (((status) != (android::OK))) { 293return status; 294} 295if (reply.readExceptionCode()) { 296status = android::FAILED_TRANSACTION; 297return status; 298} 299status = reply.readInt32(_aidl_return); 300if (((status) != (android::OK))) { 301return status; 302} 303status = reply.readBoolVector(item); 304if (((status) != (android::OK))) { 305return status; 306} 307return status; 308} 309 310android::status_t BpComplexTypeInterface::Piff(int32_t times) { 311android::Parcel data; 312android::status_t status; 313status = data.writeInterfaceToken(getInterfaceDescriptor()); 314if (((status) != (android::OK))) { 315return status; 316} 317status = data.writeInt32(times); 318if (((status) != (android::OK))) { 319return status; 320} 321status = remote()->transact(IComplexTypeInterface::PIFF, data, &reply, android::IBinder::FLAG_ONEWAY); 322if (((status) != (android::OK))) { 323return status; 324} 325if (reply.readExceptionCode()) { 326status = android::FAILED_TRANSACTION; 327return status; 328} 329return status; 330} 331 332} // namespace os 333 334} // namespace android 335)"; 336 337const char kExpectedComplexTypeServerHeaderOutput[] = 338R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 339#define AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 340 341#include <binder/IInterface.h> 342#include <android/os/IComplexTypeInterface.h> 343 344namespace android { 345 346namespace os { 347 348class BnComplexTypeInterface : public android::BnInterface<IComplexTypeInterface> { 349public: 350android::status_t onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags = 0) override; 351}; // class BnComplexTypeInterface 352 353} // namespace os 354 355} // namespace android 356 357#endif // AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_)"; 358 359const char kExpectedComplexTypeServerSourceOutput[] = 360R"(#include <android/os/BnComplexTypeInterface.h> 361#include <binder/Parcel.h> 362 363namespace android { 364 365namespace os { 366 367android::status_t BnComplexTypeInterface::onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags) { 368android::status_t status; 369switch (code) { 370case Call::SEND: 371{ 372std::vector<int32_t> in_token; 373std::vector<bool> out_item; 374int32_t _aidl_return; 375if ((!data.checkInterface(this))) { 376status = android::BAD_TYPE; 377break; 378} 379status = data.readInt32Vector(&in_token); 380if (((status) != (android::OK))) { 381break; 382} 383status = Send(in_token, &out_item, &_aidl_return); 384if (((status) != (android::OK))) { 385break; 386} 387status = reply->writeNoException(); 388if (((status) != (android::OK))) { 389break; 390} 391status = reply->writeInt32(_aidl_return); 392if (((status) != (android::OK))) { 393break; 394} 395status = reply->writeBoolVector(out_item); 396if (((status) != (android::OK))) { 397break; 398} 399} 400break; 401case Call::PIFF: 402{ 403int32_t in_times; 404if ((!data.checkInterface(this))) { 405status = android::BAD_TYPE; 406break; 407} 408status = data.readInt32(&in_times); 409if (((status) != (android::OK))) { 410break; 411} 412status = Piff(in_times); 413if (((status) != (android::OK))) { 414break; 415} 416status = reply->writeNoException(); 417if (((status) != (android::OK))) { 418break; 419} 420} 421break; 422default: 423{ 424status = android::BBinder::onTransact(code, data, reply, flags); 425} 426break; 427} 428return status; 429} 430 431} // namespace os 432 433} // namespace android 434)"; 435 436const char kExpectedComplexTypeInterfaceHeaderOutput[] = 437R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 438#define AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 439 440#include <binder/IBinder.h> 441#include <binder/IInterface.h> 442#include <cstdint> 443#include <vector> 444 445namespace android { 446 447namespace os { 448 449class IComplexTypeInterface : public android::IInterface { 450public: 451DECLARE_META_INTERFACE(ComplexTypeInterface); 452virtual android::status_t Send(const std::vector<int32_t>& token, std::vector<bool>* item, int32_t* _aidl_return) = 0; 453virtual android::status_t Piff(int32_t times) = 0; 454enum Call { 455 SEND = android::IBinder::FIRST_CALL_TRANSACTION + 0, 456 PIFF = android::IBinder::FIRST_CALL_TRANSACTION + 1, 457}; 458}; // class IComplexTypeInterface 459 460} // namespace os 461 462} // namespace android 463 464#endif // AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_)"; 465 466const char kExpectedComplexTypeInterfaceSourceOutput[] = 467R"(#include <android/os/IComplexTypeInterface.h> 468#include <android/os/BpComplexTypeInterface.h> 469 470namespace android { 471 472namespace os { 473 474IMPLEMENT_META_INTERFACE(ComplexTypeInterface, "android.os.IComplexTypeInterface"); 475 476} // namespace os 477 478} // namespace android 479)"; 480 481} // namespace 482 483class ASTTest : public ::testing::Test { 484 protected: 485 virtual const string& FilePath() = 0; 486 virtual const string& FileContents() = 0; 487 488 unique_ptr<AidlInterface> Parse() { 489 FakeIoDelegate io_delegate; 490 io_delegate.SetFileContents(FilePath(), FileContents()); 491 492 cpp::TypeNamespace types; 493 unique_ptr<AidlInterface> ret; 494 std::vector<std::unique_ptr<AidlImport>> imports; 495 int err = ::android::aidl::internals::load_and_validate_aidl( 496 {}, // no preprocessed files 497 {}, // no import paths 498 FilePath(), 499 io_delegate, 500 &types, 501 &ret, 502 &imports); 503 504 if (err) 505 return nullptr; 506 507 return ret; 508 } 509 510 void Compare(Document* doc, const char* expected) { 511 string output; 512 unique_ptr<CodeWriter> cw = GetStringWriter(&output); 513 514 doc->Write(cw.get()); 515 516 if (expected == output) { 517 return; // Success 518 } 519 520 test::PrintDiff(expected, output); 521 FAIL() << "Document contents did not match expected contents"; 522 } 523}; 524 525class PrimitiveInterfaceASTTest : public ASTTest { 526 protected: 527 const string fp_ = "android/os/IPingResponder.aidl"; 528 const string& FilePath() override { return fp_; } 529 const string& FileContents() override { return kPrimitiveInterfaceAIDL; } 530}; 531 532TEST_F(PrimitiveInterfaceASTTest, GeneratesClientHeader) { 533 unique_ptr<AidlInterface> interface = Parse(); 534 ASSERT_NE(interface, nullptr); 535 TypeNamespace types; 536 unique_ptr<Document> doc = internals::BuildClientHeader(types, *interface); 537 Compare(doc.get(), kExpectedPrimitiveClientHeaderOutput); 538} 539 540TEST_F(PrimitiveInterfaceASTTest, GeneratesClientSource) { 541 unique_ptr<AidlInterface> interface = Parse(); 542 ASSERT_NE(interface, nullptr); 543 TypeNamespace types; 544 unique_ptr<Document> doc = internals::BuildClientSource(types, *interface); 545 Compare(doc.get(), kExpectedPrimitiveClientSourceOutput); 546} 547 548TEST_F(PrimitiveInterfaceASTTest, GeneratesServerHeader) { 549 unique_ptr<AidlInterface> interface = Parse(); 550 ASSERT_NE(interface, nullptr); 551 TypeNamespace types; 552 unique_ptr<Document> doc = internals::BuildServerHeader(types, *interface); 553 Compare(doc.get(), kExpectedPrimitiveServerHeaderOutput); 554} 555 556TEST_F(PrimitiveInterfaceASTTest, GeneratesServerSource) { 557 unique_ptr<AidlInterface> interface = Parse(); 558 ASSERT_NE(interface, nullptr); 559 TypeNamespace types; 560 unique_ptr<Document> doc = internals::BuildServerSource(types, *interface); 561 Compare(doc.get(), kExpectedPrimitiveServerSourceOutput); 562} 563 564TEST_F(PrimitiveInterfaceASTTest, GeneratesInterfaceHeader) { 565 unique_ptr<AidlInterface> interface = Parse(); 566 ASSERT_NE(interface, nullptr); 567 TypeNamespace types; 568 unique_ptr<Document> doc = internals::BuildInterfaceHeader(types, *interface); 569 Compare(doc.get(), kExpectedPrimitiveInterfaceHeaderOutput); 570} 571 572TEST_F(PrimitiveInterfaceASTTest, GeneratesInterfaceSource) { 573 unique_ptr<AidlInterface> interface = Parse(); 574 ASSERT_NE(interface, nullptr); 575 TypeNamespace types; 576 unique_ptr<Document> doc = internals::BuildInterfaceSource(types, *interface); 577 Compare(doc.get(), kExpectedPrimitiveInterfaceSourceOutput); 578} 579 580class ComplexTypeInterfaceASTTest : public ASTTest { 581 protected: 582 const string fp_ = "android/os/IComplexTypeInterface.aidl"; 583 const string& FilePath() override { return fp_; } 584 const string& FileContents() override { return kComplexTypeInterfaceAIDL; } 585}; 586 587TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) { 588 unique_ptr<AidlInterface> interface = Parse(); 589 ASSERT_NE(interface, nullptr); 590 TypeNamespace types; 591 unique_ptr<Document> doc = internals::BuildClientHeader(types, *interface); 592 Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput); 593} 594 595TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) { 596 unique_ptr<AidlInterface> interface = Parse(); 597 ASSERT_NE(interface, nullptr); 598 TypeNamespace types; 599 unique_ptr<Document> doc = internals::BuildClientSource(types, *interface); 600 Compare(doc.get(), kExpectedComplexTypeClientSourceOutput); 601} 602 603TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) { 604 unique_ptr<AidlInterface> interface = Parse(); 605 ASSERT_NE(interface, nullptr); 606 TypeNamespace types; 607 unique_ptr<Document> doc = internals::BuildServerHeader(types, *interface); 608 Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput); 609} 610 611TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) { 612 unique_ptr<AidlInterface> interface = Parse(); 613 ASSERT_NE(interface, nullptr); 614 TypeNamespace types; 615 unique_ptr<Document> doc = internals::BuildServerSource(types, *interface); 616 Compare(doc.get(), kExpectedComplexTypeServerSourceOutput); 617} 618 619TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) { 620 unique_ptr<AidlInterface> interface = Parse(); 621 ASSERT_NE(interface, nullptr); 622 TypeNamespace types; 623 unique_ptr<Document> doc = internals::BuildInterfaceHeader(types, *interface); 624 Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput); 625} 626 627TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) { 628 unique_ptr<AidlInterface> interface = Parse(); 629 ASSERT_NE(interface, nullptr); 630 TypeNamespace types; 631 unique_ptr<Document> doc = internals::BuildInterfaceSource(types, *interface); 632 Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput); 633} 634 635} // namespace cpp 636} // namespace aidl 637} // namespace android 638