generate_cpp_unittest.cpp revision 0eb903eff2376941ad7e947bd5d3a32e15d89f69
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.writeString16(token); 64if (((status) != (android::OK))) { 65return status; 66} 67status = remote()->transact(IPingResponder::PING, data, &reply); 68if (((status) != (android::OK))) { 69return status; 70} 71status = reply.readInt32(_aidl_return); 72if (((status) != (android::OK))) { 73return status; 74} 75return status; 76} 77 78} // namespace os 79 80} // namespace android 81)"; 82 83const char kExpectedPrimitiveServerHeaderOutput[] = 84R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_ 85#define AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_ 86 87#include <binder/IInterface.h> 88#include <android/os/IPingResponder.h> 89 90namespace android { 91 92namespace os { 93 94class BnPingResponder : public android::BnInterface<IPingResponder> { 95public: 96android::status_t onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags = 0) override; 97}; // class BnPingResponder 98 99} // namespace os 100 101} // namespace android 102 103#endif // AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_)"; 104 105const char kExpectedPrimitiveServerSourceOutput[] = 106R"(#include <android/os/BnPingResponder.h> 107#include <binder/Parcel.h> 108 109namespace android { 110 111namespace os { 112 113android::status_t BnPingResponder::onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags) { 114android::status_t status; 115switch (code) { 116case Call::PING: 117{ 118android::String16 in_token; 119int32_t _aidl_return; 120status = data.readString16(&in_token); 121if (((status) != (android::OK))) { 122break; 123} 124status = Ping(in_token, &_aidl_return); 125if (((status) != (android::OK))) { 126break; 127} 128status = reply->writeInt32(_aidl_return); 129if (((status) != (android::OK))) { 130break; 131} 132} 133break; 134default: 135{ 136status = android::BBinder::onTransact(code, data, reply, flags); 137} 138break; 139} 140return status; 141} 142 143} // namespace os 144 145} // namespace android 146)"; 147 148const char kExpectedPrimitiveClientHeaderOutput[] = 149R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_ 150#define AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_ 151 152#include <binder/IBinder.h> 153#include <binder/IInterface.h> 154#include <utils/Errors.h> 155#include <android/os/IPingResponder.h> 156 157namespace android { 158 159namespace os { 160 161class BpPingResponder : public android::BpInterface<IPingResponder> { 162public: 163explicit BpPingResponder(const android::sp<android::IBinder>& impl); 164virtual ~BpPingResponder() = default; 165android::status_t Ping(android::String16 token, int32_t* _aidl_return) override; 166}; // class BpPingResponder 167 168} // namespace os 169 170} // namespace android 171 172#endif // AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_)"; 173 174const char kExpectedPrimitiveInterfaceHeaderOutput[] = 175R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_ 176#define AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_ 177 178#include <binder/IBinder.h> 179#include <binder/IInterface.h> 180#include <cstdint> 181#include <utils/String16.h> 182 183namespace android { 184 185namespace os { 186 187class IPingResponder : public android::IInterface { 188public: 189DECLARE_META_INTERFACE(PingResponder); 190virtual android::status_t Ping(android::String16 token, int32_t* _aidl_return) = 0; 191enum Call { 192 PING = android::IBinder::FIRST_CALL_TRANSACTION + 0, 193}; 194}; // class IPingResponder 195 196} // namespace os 197 198} // namespace android 199 200#endif // AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_)"; 201 202const char kExpectedPrimitiveInterfaceSourceOutput[] = 203R"(#include <android/os/IPingResponder.h> 204#include <android/os/BpPingResponder.h> 205 206namespace android { 207 208namespace os { 209 210IMPLEMENT_META_INTERFACE(PingResponder, "android.os.IPingResponder"); 211 212} // namespace os 213 214} // namespace android 215)"; 216 217const string kComplexTypeInterfaceAIDL = 218R"(package android.os; 219interface IComplexTypeInterface { 220 int Send(in int[] token, out boolean[] item); 221 oneway void Piff(int times); 222})"; 223 224const char kExpectedComplexTypeClientHeaderOutput[] = 225R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_ 226#define AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_ 227 228#include <binder/IBinder.h> 229#include <binder/IInterface.h> 230#include <utils/Errors.h> 231#include <android/os/IComplexTypeInterface.h> 232 233namespace android { 234 235namespace os { 236 237class BpComplexTypeInterface : public android::BpInterface<IComplexTypeInterface> { 238public: 239explicit BpComplexTypeInterface(const android::sp<android::IBinder>& impl); 240virtual ~BpComplexTypeInterface() = default; 241android::status_t Send(const std::vector<int32_t>& token, std::vector<bool>* item, int32_t* _aidl_return) override; 242android::status_t Piff(int32_t times) override; 243}; // class BpComplexTypeInterface 244 245} // namespace os 246 247} // namespace android 248 249#endif // AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_)"; 250 251const char kExpectedComplexTypeClientSourceOutput[] = 252R"(#include <android/os/BpComplexTypeInterface.h> 253#include <binder/Parcel.h> 254 255namespace android { 256 257namespace os { 258 259BpComplexTypeInterface::BpComplexTypeInterface(const android::sp<android::IBinder>& impl) 260 : BpInterface<IPingResponder>(impl){ 261} 262 263android::status_t BpComplexTypeInterface::Send(const std::vector<int32_t>& token, std::vector<bool>* item, int32_t* _aidl_return) { 264android::Parcel data; 265android::Parcel reply; 266android::status_t status; 267status = data.writeInt32Vector(token); 268if (((status) != (android::OK))) { 269return status; 270} 271status = remote()->transact(IComplexTypeInterface::SEND, data, &reply); 272if (((status) != (android::OK))) { 273return status; 274} 275status = reply.readInt32(_aidl_return); 276if (((status) != (android::OK))) { 277return status; 278} 279status = reply.readBoolVector(item); 280if (((status) != (android::OK))) { 281return status; 282} 283return status; 284} 285 286android::status_t BpComplexTypeInterface::Piff(int32_t times) { 287android::Parcel data; 288android::status_t status; 289status = data.writeInt32(times); 290if (((status) != (android::OK))) { 291return status; 292} 293status = remote()->transact(IComplexTypeInterface::PIFF, data, &reply, android::IBinder::FLAG_ONEWAY); 294if (((status) != (android::OK))) { 295return status; 296} 297return status; 298} 299 300} // namespace os 301 302} // namespace android 303)"; 304 305const char kExpectedComplexTypeServerHeaderOutput[] = 306R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 307#define AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 308 309#include <binder/IInterface.h> 310#include <android/os/IComplexTypeInterface.h> 311 312namespace android { 313 314namespace os { 315 316class BnComplexTypeInterface : public android::BnInterface<IComplexTypeInterface> { 317public: 318android::status_t onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags = 0) override; 319}; // class BnComplexTypeInterface 320 321} // namespace os 322 323} // namespace android 324 325#endif // AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_)"; 326 327const char kExpectedComplexTypeServerSourceOutput[] = 328R"(#include <android/os/BnComplexTypeInterface.h> 329#include <binder/Parcel.h> 330 331namespace android { 332 333namespace os { 334 335android::status_t BnComplexTypeInterface::onTransact(uint32_t code, const android::Parcel& data, android::Parcel* reply, uint32_t flags) { 336android::status_t status; 337switch (code) { 338case Call::SEND: 339{ 340std::vector<int32_t> in_token; 341std::vector<bool> out_item; 342int32_t _aidl_return; 343status = data.readInt32Vector(&in_token); 344if (((status) != (android::OK))) { 345break; 346} 347status = Send(in_token, &out_item, &_aidl_return); 348if (((status) != (android::OK))) { 349break; 350} 351status = reply->writeInt32(_aidl_return); 352if (((status) != (android::OK))) { 353break; 354} 355status = reply->writeBoolVector(out_item); 356if (((status) != (android::OK))) { 357break; 358} 359} 360break; 361case Call::PIFF: 362{ 363int32_t in_times; 364status = data.readInt32(&in_times); 365if (((status) != (android::OK))) { 366break; 367} 368status = Piff(in_times); 369if (((status) != (android::OK))) { 370break; 371} 372} 373break; 374default: 375{ 376status = android::BBinder::onTransact(code, data, reply, flags); 377} 378break; 379} 380return status; 381} 382 383} // namespace os 384 385} // namespace android 386)"; 387 388const char kExpectedComplexTypeInterfaceHeaderOutput[] = 389R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 390#define AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 391 392#include <binder/IBinder.h> 393#include <binder/IInterface.h> 394#include <cstdint> 395#include <vector> 396 397namespace android { 398 399namespace os { 400 401class IComplexTypeInterface : public android::IInterface { 402public: 403DECLARE_META_INTERFACE(ComplexTypeInterface); 404virtual android::status_t Send(const std::vector<int32_t>& token, std::vector<bool>* item, int32_t* _aidl_return) = 0; 405virtual android::status_t Piff(int32_t times) = 0; 406enum Call { 407 SEND = android::IBinder::FIRST_CALL_TRANSACTION + 0, 408 PIFF = android::IBinder::FIRST_CALL_TRANSACTION + 1, 409}; 410}; // class IComplexTypeInterface 411 412} // namespace os 413 414} // namespace android 415 416#endif // AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_)"; 417 418const char kExpectedComplexTypeInterfaceSourceOutput[] = 419R"(#include <android/os/IComplexTypeInterface.h> 420#include <android/os/BpComplexTypeInterface.h> 421 422namespace android { 423 424namespace os { 425 426IMPLEMENT_META_INTERFACE(ComplexTypeInterface, "android.os.IComplexTypeInterface"); 427 428} // namespace os 429 430} // namespace android 431)"; 432 433} // namespace 434 435class ASTTest : public ::testing::Test { 436 protected: 437 virtual const string& FilePath() = 0; 438 virtual const string& FileContents() = 0; 439 440 unique_ptr<AidlInterface> Parse() { 441 FakeIoDelegate io_delegate; 442 io_delegate.SetFileContents(FilePath(), FileContents()); 443 444 cpp::TypeNamespace types; 445 unique_ptr<AidlInterface> ret; 446 std::vector<std::unique_ptr<AidlImport>> imports; 447 int err = ::android::aidl::internals::load_and_validate_aidl( 448 {}, // no preprocessed files 449 {}, // no import paths 450 FilePath(), 451 io_delegate, 452 &types, 453 &ret, 454 &imports); 455 456 if (err) 457 return nullptr; 458 459 return ret; 460 } 461 462 void Compare(Document* doc, const char* expected) { 463 string output; 464 unique_ptr<CodeWriter> cw = GetStringWriter(&output); 465 466 doc->Write(cw.get()); 467 468 if (expected == output) { 469 return; // Success 470 } 471 472 test::PrintDiff(expected, output); 473 FAIL() << "Document contents did not match expected contents"; 474 } 475}; 476 477class PrimitiveInterfaceASTTest : public ASTTest { 478 protected: 479 const string fp_ = "android/os/IPingResponder.aidl"; 480 const string& FilePath() override { return fp_; } 481 const string& FileContents() override { return kPrimitiveInterfaceAIDL; } 482}; 483 484TEST_F(PrimitiveInterfaceASTTest, GeneratesClientHeader) { 485 unique_ptr<AidlInterface> interface = Parse(); 486 ASSERT_NE(interface, nullptr); 487 TypeNamespace types; 488 unique_ptr<Document> doc = internals::BuildClientHeader(types, *interface); 489 Compare(doc.get(), kExpectedPrimitiveClientHeaderOutput); 490} 491 492TEST_F(PrimitiveInterfaceASTTest, GeneratesClientSource) { 493 unique_ptr<AidlInterface> interface = Parse(); 494 ASSERT_NE(interface, nullptr); 495 TypeNamespace types; 496 unique_ptr<Document> doc = internals::BuildClientSource(types, *interface); 497 Compare(doc.get(), kExpectedPrimitiveClientSourceOutput); 498} 499 500TEST_F(PrimitiveInterfaceASTTest, GeneratesServerHeader) { 501 unique_ptr<AidlInterface> interface = Parse(); 502 ASSERT_NE(interface, nullptr); 503 TypeNamespace types; 504 unique_ptr<Document> doc = internals::BuildServerHeader(types, *interface); 505 Compare(doc.get(), kExpectedPrimitiveServerHeaderOutput); 506} 507 508TEST_F(PrimitiveInterfaceASTTest, GeneratesServerSource) { 509 unique_ptr<AidlInterface> interface = Parse(); 510 ASSERT_NE(interface, nullptr); 511 TypeNamespace types; 512 unique_ptr<Document> doc = internals::BuildServerSource(types, *interface); 513 Compare(doc.get(), kExpectedPrimitiveServerSourceOutput); 514} 515 516TEST_F(PrimitiveInterfaceASTTest, GeneratesInterfaceHeader) { 517 unique_ptr<AidlInterface> interface = Parse(); 518 ASSERT_NE(interface, nullptr); 519 TypeNamespace types; 520 unique_ptr<Document> doc = internals::BuildInterfaceHeader(types, *interface); 521 Compare(doc.get(), kExpectedPrimitiveInterfaceHeaderOutput); 522} 523 524TEST_F(PrimitiveInterfaceASTTest, GeneratesInterfaceSource) { 525 unique_ptr<AidlInterface> interface = Parse(); 526 ASSERT_NE(interface, nullptr); 527 TypeNamespace types; 528 unique_ptr<Document> doc = internals::BuildInterfaceSource(types, *interface); 529 Compare(doc.get(), kExpectedPrimitiveInterfaceSourceOutput); 530} 531 532class ComplexTypeInterfaceASTTest : public ASTTest { 533 protected: 534 const string fp_ = "android/os/IComplexTypeInterface.aidl"; 535 const string& FilePath() override { return fp_; } 536 const string& FileContents() override { return kComplexTypeInterfaceAIDL; } 537}; 538 539TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) { 540 unique_ptr<AidlInterface> interface = Parse(); 541 ASSERT_NE(interface, nullptr); 542 TypeNamespace types; 543 unique_ptr<Document> doc = internals::BuildClientHeader(types, *interface); 544 Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput); 545} 546 547TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) { 548 unique_ptr<AidlInterface> interface = Parse(); 549 ASSERT_NE(interface, nullptr); 550 TypeNamespace types; 551 unique_ptr<Document> doc = internals::BuildClientSource(types, *interface); 552 Compare(doc.get(), kExpectedComplexTypeClientSourceOutput); 553} 554 555TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) { 556 unique_ptr<AidlInterface> interface = Parse(); 557 ASSERT_NE(interface, nullptr); 558 TypeNamespace types; 559 unique_ptr<Document> doc = internals::BuildServerHeader(types, *interface); 560 Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput); 561} 562 563TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) { 564 unique_ptr<AidlInterface> interface = Parse(); 565 ASSERT_NE(interface, nullptr); 566 TypeNamespace types; 567 unique_ptr<Document> doc = internals::BuildServerSource(types, *interface); 568 Compare(doc.get(), kExpectedComplexTypeServerSourceOutput); 569} 570 571TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) { 572 unique_ptr<AidlInterface> interface = Parse(); 573 ASSERT_NE(interface, nullptr); 574 TypeNamespace types; 575 unique_ptr<Document> doc = internals::BuildInterfaceHeader(types, *interface); 576 Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput); 577} 578 579TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) { 580 unique_ptr<AidlInterface> interface = Parse(); 581 ASSERT_NE(interface, nullptr); 582 TypeNamespace types; 583 unique_ptr<Document> doc = internals::BuildInterfaceSource(types, *interface); 584 Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput); 585} 586 587} // namespace cpp 588} // namespace aidl 589} // namespace android 590