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