generate_cpp_unittest.cpp revision 1227d6135418a6a876666adcf4f8d9b498f17647
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<IComplexTypeInterface>(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::Parcel reply; 313android::status_t status; 314status = data.writeInterfaceToken(getInterfaceDescriptor()); 315if (((status) != (android::OK))) { 316return status; 317} 318status = data.writeInt32(times); 319if (((status) != (android::OK))) { 320return status; 321} 322status = remote()->transact(IComplexTypeInterface::PIFF, data, &reply, android::IBinder::FLAG_ONEWAY); 323if (((status) != (android::OK))) { 324return status; 325} 326return status; 327} 328 329} // namespace os 330 331} // namespace android 332)"; 333 334const char kExpectedComplexTypeServerHeaderOutput[] = 335R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 336#define AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 337 338#include <binder/IInterface.h> 339#include <android/os/IComplexTypeInterface.h> 340 341namespace android { 342 343namespace os { 344 345class BnComplexTypeInterface : public android::BnInterface<IComplexTypeInterface> { 346public: 347android::status_t onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags = 0) override; 348}; // class BnComplexTypeInterface 349 350} // namespace os 351 352} // namespace android 353 354#endif // AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_)"; 355 356const char kExpectedComplexTypeServerSourceOutput[] = 357R"(#include <android/os/BnComplexTypeInterface.h> 358#include <binder/Parcel.h> 359 360namespace android { 361 362namespace os { 363 364android::status_t BnComplexTypeInterface::onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags) { 365android::status_t status; 366switch (code) { 367case Call::SEND: 368{ 369std::vector<int32_t> in_token; 370std::vector<bool> out_item; 371int32_t _aidl_return; 372if ((!data.checkInterface(this))) { 373status = android::BAD_TYPE; 374break; 375} 376status = data.readInt32Vector(&in_token); 377if (((status) != (android::OK))) { 378break; 379} 380status = Send(in_token, &out_item, &_aidl_return); 381if (((status) != (android::OK))) { 382break; 383} 384status = reply->writeNoException(); 385if (((status) != (android::OK))) { 386break; 387} 388status = reply->writeInt32(_aidl_return); 389if (((status) != (android::OK))) { 390break; 391} 392status = reply->writeBoolVector(out_item); 393if (((status) != (android::OK))) { 394break; 395} 396} 397break; 398case Call::PIFF: 399{ 400int32_t in_times; 401if ((!data.checkInterface(this))) { 402status = android::BAD_TYPE; 403break; 404} 405status = data.readInt32(&in_times); 406if (((status) != (android::OK))) { 407break; 408} 409status = Piff(in_times); 410if (((status) != (android::OK))) { 411break; 412} 413status = reply->writeNoException(); 414if (((status) != (android::OK))) { 415break; 416} 417} 418break; 419default: 420{ 421status = android::BBinder::onTransact(code, data, reply, flags); 422} 423break; 424} 425return status; 426} 427 428} // namespace os 429 430} // namespace android 431)"; 432 433const char kExpectedComplexTypeInterfaceHeaderOutput[] = 434R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 435#define AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 436 437#include <binder/IBinder.h> 438#include <binder/IInterface.h> 439#include <cstdint> 440#include <vector> 441 442namespace android { 443 444namespace os { 445 446class IComplexTypeInterface : public android::IInterface { 447public: 448DECLARE_META_INTERFACE(ComplexTypeInterface); 449virtual android::status_t Send(const std::vector<int32_t>& token, std::vector<bool>* item, int32_t* _aidl_return) = 0; 450virtual android::status_t Piff(int32_t times) = 0; 451enum Call { 452 SEND = android::IBinder::FIRST_CALL_TRANSACTION + 0, 453 PIFF = android::IBinder::FIRST_CALL_TRANSACTION + 1, 454}; 455}; // class IComplexTypeInterface 456 457} // namespace os 458 459} // namespace android 460 461#endif // AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_)"; 462 463const char kExpectedComplexTypeInterfaceSourceOutput[] = 464R"(#include <android/os/IComplexTypeInterface.h> 465#include <android/os/BpComplexTypeInterface.h> 466 467namespace android { 468 469namespace os { 470 471IMPLEMENT_META_INTERFACE(ComplexTypeInterface, "android.os.IComplexTypeInterface"); 472 473} // namespace os 474 475} // namespace android 476)"; 477 478} // namespace 479 480class ASTTest : public ::testing::Test { 481 protected: 482 virtual const string& FilePath() = 0; 483 virtual const string& FileContents() = 0; 484 485 unique_ptr<AidlInterface> Parse() { 486 FakeIoDelegate io_delegate; 487 io_delegate.SetFileContents(FilePath(), FileContents()); 488 489 cpp::TypeNamespace types; 490 unique_ptr<AidlInterface> ret; 491 std::vector<std::unique_ptr<AidlImport>> imports; 492 int err = ::android::aidl::internals::load_and_validate_aidl( 493 {}, // no preprocessed files 494 {}, // no import paths 495 FilePath(), 496 io_delegate, 497 &types, 498 &ret, 499 &imports); 500 501 if (err) 502 return nullptr; 503 504 return ret; 505 } 506 507 void Compare(Document* doc, const char* expected) { 508 string output; 509 unique_ptr<CodeWriter> cw = GetStringWriter(&output); 510 511 doc->Write(cw.get()); 512 513 if (expected == output) { 514 return; // Success 515 } 516 517 test::PrintDiff(expected, output); 518 FAIL() << "Document contents did not match expected contents"; 519 } 520}; 521 522class PrimitiveInterfaceASTTest : public ASTTest { 523 protected: 524 const string fp_ = "android/os/IPingResponder.aidl"; 525 const string& FilePath() override { return fp_; } 526 const string& FileContents() override { return kPrimitiveInterfaceAIDL; } 527}; 528 529TEST_F(PrimitiveInterfaceASTTest, GeneratesClientHeader) { 530 unique_ptr<AidlInterface> interface = Parse(); 531 ASSERT_NE(interface, nullptr); 532 TypeNamespace types; 533 unique_ptr<Document> doc = internals::BuildClientHeader(types, *interface); 534 Compare(doc.get(), kExpectedPrimitiveClientHeaderOutput); 535} 536 537TEST_F(PrimitiveInterfaceASTTest, GeneratesClientSource) { 538 unique_ptr<AidlInterface> interface = Parse(); 539 ASSERT_NE(interface, nullptr); 540 TypeNamespace types; 541 unique_ptr<Document> doc = internals::BuildClientSource(types, *interface); 542 Compare(doc.get(), kExpectedPrimitiveClientSourceOutput); 543} 544 545TEST_F(PrimitiveInterfaceASTTest, GeneratesServerHeader) { 546 unique_ptr<AidlInterface> interface = Parse(); 547 ASSERT_NE(interface, nullptr); 548 TypeNamespace types; 549 unique_ptr<Document> doc = internals::BuildServerHeader(types, *interface); 550 Compare(doc.get(), kExpectedPrimitiveServerHeaderOutput); 551} 552 553TEST_F(PrimitiveInterfaceASTTest, GeneratesServerSource) { 554 unique_ptr<AidlInterface> interface = Parse(); 555 ASSERT_NE(interface, nullptr); 556 TypeNamespace types; 557 unique_ptr<Document> doc = internals::BuildServerSource(types, *interface); 558 Compare(doc.get(), kExpectedPrimitiveServerSourceOutput); 559} 560 561TEST_F(PrimitiveInterfaceASTTest, GeneratesInterfaceHeader) { 562 unique_ptr<AidlInterface> interface = Parse(); 563 ASSERT_NE(interface, nullptr); 564 TypeNamespace types; 565 unique_ptr<Document> doc = internals::BuildInterfaceHeader(types, *interface); 566 Compare(doc.get(), kExpectedPrimitiveInterfaceHeaderOutput); 567} 568 569TEST_F(PrimitiveInterfaceASTTest, GeneratesInterfaceSource) { 570 unique_ptr<AidlInterface> interface = Parse(); 571 ASSERT_NE(interface, nullptr); 572 TypeNamespace types; 573 unique_ptr<Document> doc = internals::BuildInterfaceSource(types, *interface); 574 Compare(doc.get(), kExpectedPrimitiveInterfaceSourceOutput); 575} 576 577class ComplexTypeInterfaceASTTest : public ASTTest { 578 protected: 579 const string fp_ = "android/os/IComplexTypeInterface.aidl"; 580 const string& FilePath() override { return fp_; } 581 const string& FileContents() override { return kComplexTypeInterfaceAIDL; } 582}; 583 584TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) { 585 unique_ptr<AidlInterface> interface = Parse(); 586 ASSERT_NE(interface, nullptr); 587 TypeNamespace types; 588 unique_ptr<Document> doc = internals::BuildClientHeader(types, *interface); 589 Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput); 590} 591 592TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) { 593 unique_ptr<AidlInterface> interface = Parse(); 594 ASSERT_NE(interface, nullptr); 595 TypeNamespace types; 596 unique_ptr<Document> doc = internals::BuildClientSource(types, *interface); 597 Compare(doc.get(), kExpectedComplexTypeClientSourceOutput); 598} 599 600TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) { 601 unique_ptr<AidlInterface> interface = Parse(); 602 ASSERT_NE(interface, nullptr); 603 TypeNamespace types; 604 unique_ptr<Document> doc = internals::BuildServerHeader(types, *interface); 605 Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput); 606} 607 608TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) { 609 unique_ptr<AidlInterface> interface = Parse(); 610 ASSERT_NE(interface, nullptr); 611 TypeNamespace types; 612 unique_ptr<Document> doc = internals::BuildServerSource(types, *interface); 613 Compare(doc.get(), kExpectedComplexTypeServerSourceOutput); 614} 615 616TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) { 617 unique_ptr<AidlInterface> interface = Parse(); 618 ASSERT_NE(interface, nullptr); 619 TypeNamespace types; 620 unique_ptr<Document> doc = internals::BuildInterfaceHeader(types, *interface); 621 Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput); 622} 623 624TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) { 625 unique_ptr<AidlInterface> interface = Parse(); 626 ASSERT_NE(interface, nullptr); 627 TypeNamespace types; 628 unique_ptr<Document> doc = internals::BuildInterfaceSource(types, *interface); 629 Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput); 630} 631 632} // namespace cpp 633} // namespace aidl 634} // namespace android 635