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