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