1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <fidl/test/spaceship/c/fidl.h>
6 #include <lib/async-loop/loop.h>
7 #include <lib/fidl-async/bind.h>
8 #include <string.h>
9 #include <zircon/fidl.h>
10 #include <zircon/syscalls.h>
11 
12 #include <unittest/unittest.h>
13 
SpaceShip_AdjustHeading(void * ctx,const uint32_t * stars_data,size_t stars_count,fidl_txn_t * txn)14 static zx_status_t SpaceShip_AdjustHeading(void* ctx, const uint32_t* stars_data, size_t stars_count, fidl_txn_t* txn) {
15     EXPECT_EQ(3u, stars_count, "");
16     EXPECT_EQ(11u, stars_data[0], "");
17     EXPECT_EQ(0u, stars_data[1], "");
18     EXPECT_EQ(UINT32_MAX, stars_data[2], "");
19     return fidl_test_spaceship_SpaceShipAdjustHeading_reply(txn, -12);
20 }
21 
SpaceShip_ScanForLifeforms(void * ctx,fidl_txn_t * txn)22 static zx_status_t SpaceShip_ScanForLifeforms(void* ctx, fidl_txn_t* txn) {
23     const uint32_t lifesigns[5] = {42u, 43u, UINT32_MAX, 0u, 9u};
24     return fidl_test_spaceship_SpaceShipScanForLifeforms_reply(txn, lifesigns, 5);
25 }
26 
SpaceShip_ScanForTensorLifeforms(void * ctx,fidl_txn_t * txn)27 static zx_status_t SpaceShip_ScanForTensorLifeforms(void* ctx, fidl_txn_t* txn) {
28     uint32_t lifesigns[8][5][3] = {};
29     // fill the array with increasing counter
30     uint32_t counter = 0;
31     for (size_t i = 0; i < 8; i++) {
32         for (size_t j = 0; j < 5; j++) {
33             for (size_t k = 0; k < 3; k++) {
34                 lifesigns[i][j][k] = counter;
35                 counter += 1;
36             }
37         }
38     }
39     return fidl_test_spaceship_SpaceShipScanForTensorLifeforms_reply(txn, lifesigns);
40 }
41 
SpaceShip_SetAstrometricsListener(void * ctx,zx_handle_t listener)42 static zx_status_t SpaceShip_SetAstrometricsListener(void* ctx, zx_handle_t listener) {
43     EXPECT_EQ(ZX_OK, fidl_test_spaceship_AstrometricsListenerOnNova(listener), "");
44     EXPECT_EQ(ZX_OK, zx_handle_close(listener), "");
45     return ZX_OK;
46 }
47 
SpaceShip_SetDefenseCondition(void * ctx,fidl_test_spaceship_Alert alert)48 static zx_status_t SpaceShip_SetDefenseCondition(void* ctx, fidl_test_spaceship_Alert alert) {
49     EXPECT_EQ(fidl_test_spaceship_Alert_RED, alert, "");
50     return ZX_OK;
51 }
52 
SpaceShip_GetFuelRemaining(void * ctx,zx_handle_t cancel,fidl_txn_t * txn)53 static zx_status_t SpaceShip_GetFuelRemaining(void* ctx, zx_handle_t cancel, fidl_txn_t* txn) {
54     EXPECT_EQ(ZX_HANDLE_INVALID, cancel, "");
55     const fidl_test_spaceship_FuelLevel level = {
56         .reaction_mass = 1641u,
57     };
58     return fidl_test_spaceship_SpaceShipGetFuelRemaining_reply(txn, ZX_OK, &level);
59 }
60 
SpaceShip_AddFuelTank(void * ctx,const fidl_test_spaceship_FuelLevel * level,fidl_txn_t * txn)61 static zx_status_t SpaceShip_AddFuelTank(void* ctx, const fidl_test_spaceship_FuelLevel* level, fidl_txn_t* txn) {
62     return fidl_test_spaceship_SpaceShipAddFuelTank_reply(txn, level->reaction_mass / 2);
63 }
64 
SpaceShip_ReportAstrologicalData(void * ctx,const fidl_test_spaceship_AstrologicalData * data,fidl_txn_t * txn)65 static zx_status_t SpaceShip_ReportAstrologicalData(void* ctx, const fidl_test_spaceship_AstrologicalData* data, fidl_txn_t* txn) {
66     EXPECT_EQ(data->tag, fidl_test_spaceship_AstrologicalDataTag_star, "");
67     for (size_t idx = 0; idx < sizeof(data->star.data); ++idx) {
68         EXPECT_EQ(42, data->star.data[idx], "");
69     }
70 
71     const zx_status_t status = ZX_OK;
72     return fidl_test_spaceship_SpaceShipReportAstrologicalData_reply(txn, status);
73 }
74 
75 static const fidl_test_spaceship_SpaceShip_ops_t kOps = {
76     .AdjustHeading = SpaceShip_AdjustHeading,
77     .ScanForLifeforms = SpaceShip_ScanForLifeforms,
78     .SetAstrometricsListener = SpaceShip_SetAstrometricsListener,
79     .SetDefenseCondition = SpaceShip_SetDefenseCondition,
80     .GetFuelRemaining = SpaceShip_GetFuelRemaining,
81     .AddFuelTank = SpaceShip_AddFuelTank,
82     .ScanForTensorLifeforms = SpaceShip_ScanForTensorLifeforms,
83     .ReportAstrologicalData = SpaceShip_ReportAstrologicalData,
84 };
85 
spaceship_test(void)86 static bool spaceship_test(void) {
87     BEGIN_TEST;
88 
89     zx_handle_t client, server;
90     zx_status_t status = zx_channel_create(0, &client, &server);
91     ASSERT_EQ(ZX_OK, status, "");
92 
93     async_loop_t* loop = NULL;
94     ASSERT_EQ(ZX_OK, async_loop_create(&kAsyncLoopConfigNoAttachToThread, &loop), "");
95     ASSERT_EQ(ZX_OK, async_loop_start_thread(loop, "spaceship-dispatcher", NULL), "");
96 
97     async_dispatcher_t* dispatcher = async_loop_get_dispatcher(loop);
98     fidl_bind(dispatcher, server, (fidl_dispatch_t*)fidl_test_spaceship_SpaceShip_dispatch, NULL, &kOps);
99 
100     {
101         const uint32_t stars[3] = {11u, 0u, UINT32_MAX};
102         int8_t result = 0;
103         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipAdjustHeading(client, stars, 3, &result), "");
104         ASSERT_EQ(-12, result, "");
105     }
106 
107     {
108         const uint32_t num_stars_overflow = fidl_test_spaceship_MaxStarsAdjustHeading * 2;
109         const uint32_t stars[num_stars_overflow];
110         int8_t result = 0;
111         ASSERT_EQ(
112             ZX_ERR_INVALID_ARGS,
113             fidl_test_spaceship_SpaceShipAdjustHeading(client, stars, num_stars_overflow, &result),
114             "");
115     }
116 
117     {
118         int8_t result = 0;
119         ASSERT_EQ(
120             ZX_ERR_INVALID_ARGS,
121             fidl_test_spaceship_SpaceShipAdjustHeading(client, NULL, 1 << 31, &result),
122             "");
123     }
124 
125     {
126         uint32_t lifesigns[64];
127         size_t actual = 0;
128         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipScanForLifeforms(client, lifesigns, 64, &actual), "");
129         ASSERT_EQ(5u, actual, "");
130         ASSERT_EQ(42u, lifesigns[0], "");
131         ASSERT_EQ(43u, lifesigns[1], "");
132         ASSERT_EQ(UINT32_MAX, lifesigns[2], "");
133         ASSERT_EQ(0u, lifesigns[3], "");
134         ASSERT_EQ(9u, lifesigns[4], "");
135     }
136 
137     {
138         uint32_t lifesigns[8][5][3];
139         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipScanForTensorLifeforms(client, lifesigns), "");
140         uint32_t counter = 0;
141         for (size_t i = 0; i < 8; i++) {
142             for (size_t j = 0; j < 5; j++) {
143                 for (size_t k = 0; k < 3; k++) {
144                     ASSERT_EQ(counter, lifesigns[i][j][k], "");
145                     counter += 1;
146                 }
147             }
148         }
149     }
150 
151     {
152         zx_handle_t listener_client, listener_server;
153         status = zx_channel_create(0, &listener_client, &listener_server);
154         ASSERT_EQ(ZX_OK, status, "");
155         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipSetAstrometricsListener(client, listener_client), "");
156         ASSERT_EQ(ZX_OK, zx_object_wait_one(listener_server, ZX_CHANNEL_READABLE, ZX_TIME_INFINITE, NULL), "");
157         ASSERT_EQ(ZX_OK, zx_handle_close(listener_server), "");
158     }
159 
160     {
161         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipSetDefenseCondition(client, fidl_test_spaceship_Alert_RED), "");
162     }
163 
164     {
165         fidl_test_spaceship_FuelLevel level;
166         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipGetFuelRemaining(client, ZX_HANDLE_INVALID, &status, &level), "");
167         ASSERT_EQ(ZX_OK, status, "");
168         ASSERT_EQ(1641u, level.reaction_mass, "");
169     }
170 
171     {
172         fidl_test_spaceship_FuelLevel level = {
173             .reaction_mass = 9482,
174         };
175         uint32_t out_consumed = 0u;
176         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipAddFuelTank(client, &level, &out_consumed), "");
177         ASSERT_EQ(4741u, out_consumed, "");
178     }
179 
180     {
181         fidl_test_spaceship_AstrologicalData data = {};
182         data.tag = fidl_test_spaceship_AstrologicalDataTag_star;
183         memset(&data.star, 42, sizeof(data.star));
184         ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipReportAstrologicalData(client, &data, &status), "");
185         ASSERT_EQ(ZX_OK, status, "");
186     }
187 
188     ASSERT_EQ(ZX_OK, zx_handle_close(client), "");
189 
190     async_loop_destroy(loop);
191 
192     END_TEST;
193 }
194 
195 BEGIN_TEST_CASE(spaceship_tests)
196 RUN_NAMED_TEST("fidl.test.spaceship.SpaceShip test", spaceship_test)
197 END_TEST_CASE(spaceship_tests);
198