1*ec63e07aSXin Li //
2*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
3*ec63e07aSXin Li // you may not use this file except in compliance with the License.
4*ec63e07aSXin Li // You may obtain a copy of the License at
5*ec63e07aSXin Li //
6*ec63e07aSXin Li // https://www.apache.org/licenses/LICENSE-2.0
7*ec63e07aSXin Li //
8*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
9*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
10*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11*ec63e07aSXin Li // See the License for the specific language governing permissions and
12*ec63e07aSXin Li // limitations under the License.
13*ec63e07aSXin Li
14*ec63e07aSXin Li // Unittest for the sandbox2::Comms class.
15*ec63e07aSXin Li
16*ec63e07aSXin Li #include "sandboxed_api/sandbox2/comms.h"
17*ec63e07aSXin Li
18*ec63e07aSXin Li #include <fcntl.h>
19*ec63e07aSXin Li #include <sys/socket.h>
20*ec63e07aSXin Li #include <sys/types.h>
21*ec63e07aSXin Li #include <unistd.h>
22*ec63e07aSXin Li
23*ec63e07aSXin Li #include <cstdint>
24*ec63e07aSXin Li #include <cstring>
25*ec63e07aSXin Li #include <functional>
26*ec63e07aSXin Li #include <memory>
27*ec63e07aSXin Li #include <string>
28*ec63e07aSXin Li #include <thread> // NOLINT(build/c++11)
29*ec63e07aSXin Li #include <vector>
30*ec63e07aSXin Li
31*ec63e07aSXin Li #include "gmock/gmock.h"
32*ec63e07aSXin Li #include "gtest/gtest.h"
33*ec63e07aSXin Li #include "absl/container/fixed_array.h"
34*ec63e07aSXin Li #include "absl/log/check.h"
35*ec63e07aSXin Li #include "absl/log/log.h"
36*ec63e07aSXin Li #include "absl/status/status.h"
37*ec63e07aSXin Li #include "absl/strings/string_view.h"
38*ec63e07aSXin Li #include "sandboxed_api/sandbox2/comms_test.pb.h"
39*ec63e07aSXin Li #include "sandboxed_api/util/status_matchers.h"
40*ec63e07aSXin Li
41*ec63e07aSXin Li using ::sapi::IsOk;
42*ec63e07aSXin Li using ::sapi::StatusIs;
43*ec63e07aSXin Li using ::testing::Eq;
44*ec63e07aSXin Li using ::testing::IsFalse;
45*ec63e07aSXin Li using ::testing::IsTrue;
46*ec63e07aSXin Li
47*ec63e07aSXin Li namespace sandbox2 {
48*ec63e07aSXin Li
49*ec63e07aSXin Li using CommunicationHandler = std::function<void(Comms* comms)>;
50*ec63e07aSXin Li
51*ec63e07aSXin Li constexpr char kProtoStr[] = "ABCD";
NullTestString()52*ec63e07aSXin Li static absl::string_view NullTestString() {
53*ec63e07aSXin Li static constexpr char kHelperStr[] = "test\0\n\r\t\x01\x02";
54*ec63e07aSXin Li return absl::string_view(kHelperStr, sizeof(kHelperStr) - 1);
55*ec63e07aSXin Li }
56*ec63e07aSXin Li
57*ec63e07aSXin Li // Helper function that handles the communication between the two handler
58*ec63e07aSXin Li // functions.
HandleCommunication(const CommunicationHandler & a,const CommunicationHandler & b)59*ec63e07aSXin Li void HandleCommunication(const CommunicationHandler& a,
60*ec63e07aSXin Li const CommunicationHandler& b) {
61*ec63e07aSXin Li int sv[2];
62*ec63e07aSXin Li CHECK_NE(socketpair(AF_UNIX, SOCK_STREAM, 0, sv), -1);
63*ec63e07aSXin Li Comms comms(sv[0]);
64*ec63e07aSXin Li
65*ec63e07aSXin Li // Start handler a.
66*ec63e07aSXin Li std::thread remote([sv, &a]() {
67*ec63e07aSXin Li Comms my_comms(sv[1]);
68*ec63e07aSXin Li a(&my_comms);
69*ec63e07aSXin Li });
70*ec63e07aSXin Li
71*ec63e07aSXin Li // Accept connection and run handler b.
72*ec63e07aSXin Li b(&comms);
73*ec63e07aSXin Li remote.join();
74*ec63e07aSXin Li }
75*ec63e07aSXin Li
TEST(CommsTest,TestSendRecv8)76*ec63e07aSXin Li TEST(CommsTest, TestSendRecv8) {
77*ec63e07aSXin Li auto a = [](Comms* comms) {
78*ec63e07aSXin Li // Send Uint8.
79*ec63e07aSXin Li ASSERT_THAT(comms->SendUint8(192), IsTrue());
80*ec63e07aSXin Li
81*ec63e07aSXin Li // Recv Int8.
82*ec63e07aSXin Li int8_t tmp8;
83*ec63e07aSXin Li ASSERT_THAT(comms->RecvInt8(&tmp8), IsTrue());
84*ec63e07aSXin Li EXPECT_THAT(tmp8, Eq(-7));
85*ec63e07aSXin Li };
86*ec63e07aSXin Li auto b = [](Comms* comms) {
87*ec63e07aSXin Li // Recv Uint8.
88*ec63e07aSXin Li uint8_t tmpu8;
89*ec63e07aSXin Li ASSERT_THAT(comms->RecvUint8(&tmpu8), IsTrue());
90*ec63e07aSXin Li EXPECT_THAT(tmpu8, Eq(192));
91*ec63e07aSXin Li
92*ec63e07aSXin Li // Send Int8.
93*ec63e07aSXin Li ASSERT_THAT(comms->SendInt8(-7), IsTrue());
94*ec63e07aSXin Li };
95*ec63e07aSXin Li HandleCommunication(a, b);
96*ec63e07aSXin Li }
97*ec63e07aSXin Li
TEST(CommsTest,TestSendRecv16)98*ec63e07aSXin Li TEST(CommsTest, TestSendRecv16) {
99*ec63e07aSXin Li auto a = [](Comms* comms) {
100*ec63e07aSXin Li // Send Uint16.
101*ec63e07aSXin Li ASSERT_THAT(comms->SendUint16(40001), IsTrue());
102*ec63e07aSXin Li
103*ec63e07aSXin Li // Recv Int16.
104*ec63e07aSXin Li int16_t tmp16;
105*ec63e07aSXin Li ASSERT_THAT(comms->RecvInt16(&tmp16), IsTrue());
106*ec63e07aSXin Li EXPECT_THAT(tmp16, Eq(-22050));
107*ec63e07aSXin Li };
108*ec63e07aSXin Li auto b = [](Comms* comms) {
109*ec63e07aSXin Li // Recv Uint16.
110*ec63e07aSXin Li uint16_t tmpu16;
111*ec63e07aSXin Li ASSERT_THAT(comms->RecvUint16(&tmpu16), IsTrue());
112*ec63e07aSXin Li EXPECT_THAT(tmpu16, Eq(40001));
113*ec63e07aSXin Li
114*ec63e07aSXin Li // Send Int16.
115*ec63e07aSXin Li ASSERT_THAT(comms->SendInt16(-22050), IsTrue());
116*ec63e07aSXin Li };
117*ec63e07aSXin Li HandleCommunication(a, b);
118*ec63e07aSXin Li }
119*ec63e07aSXin Li
TEST(CommsTest,TestSendRecv32)120*ec63e07aSXin Li TEST(CommsTest, TestSendRecv32) {
121*ec63e07aSXin Li auto a = [](Comms* comms) {
122*ec63e07aSXin Li // SendUint32.
123*ec63e07aSXin Li ASSERT_THAT(comms->SendUint32(3221225472UL), IsTrue());
124*ec63e07aSXin Li
125*ec63e07aSXin Li // Recv Int32.
126*ec63e07aSXin Li int32_t tmp32;
127*ec63e07aSXin Li ASSERT_THAT(comms->RecvInt32(&tmp32), IsTrue());
128*ec63e07aSXin Li EXPECT_THAT(tmp32, Eq(-1073741824));
129*ec63e07aSXin Li };
130*ec63e07aSXin Li auto b = [](Comms* comms) {
131*ec63e07aSXin Li // Recv Uint32.
132*ec63e07aSXin Li uint32_t tmpu32;
133*ec63e07aSXin Li ASSERT_THAT(comms->RecvUint32(&tmpu32), IsTrue());
134*ec63e07aSXin Li EXPECT_THAT(tmpu32, Eq(3221225472UL));
135*ec63e07aSXin Li
136*ec63e07aSXin Li // Send Int32.
137*ec63e07aSXin Li ASSERT_THAT(comms->SendInt32(-1073741824), IsTrue());
138*ec63e07aSXin Li };
139*ec63e07aSXin Li HandleCommunication(a, b);
140*ec63e07aSXin Li }
141*ec63e07aSXin Li
TEST(CommsTest,TestSendRecv64)142*ec63e07aSXin Li TEST(CommsTest, TestSendRecv64) {
143*ec63e07aSXin Li auto a = [](Comms* comms) {
144*ec63e07aSXin Li // SendUint64.
145*ec63e07aSXin Li ASSERT_THAT(comms->SendUint64(1099511627776ULL), IsTrue());
146*ec63e07aSXin Li
147*ec63e07aSXin Li // Recv Int64.
148*ec63e07aSXin Li int64_t tmp64;
149*ec63e07aSXin Li ASSERT_THAT(comms->RecvInt64(&tmp64), IsTrue());
150*ec63e07aSXin Li EXPECT_THAT(tmp64, Eq(-1099511627776LL));
151*ec63e07aSXin Li };
152*ec63e07aSXin Li auto b = [](Comms* comms) {
153*ec63e07aSXin Li // Recv Uint64.
154*ec63e07aSXin Li uint64_t tmpu64;
155*ec63e07aSXin Li ASSERT_THAT(comms->RecvUint64(&tmpu64), IsTrue());
156*ec63e07aSXin Li EXPECT_THAT(tmpu64, Eq(1099511627776ULL));
157*ec63e07aSXin Li
158*ec63e07aSXin Li // Send Int64.
159*ec63e07aSXin Li ASSERT_THAT(comms->SendInt64(-1099511627776LL), IsTrue());
160*ec63e07aSXin Li };
161*ec63e07aSXin Li HandleCommunication(a, b);
162*ec63e07aSXin Li }
163*ec63e07aSXin Li
TEST(CommsTest,TestTypeMismatch)164*ec63e07aSXin Li TEST(CommsTest, TestTypeMismatch) {
165*ec63e07aSXin Li auto a = [](Comms* comms) {
166*ec63e07aSXin Li uint8_t tmpu8;
167*ec63e07aSXin Li // Receive Int8 (but Uint8 expected).
168*ec63e07aSXin Li EXPECT_THAT(comms->RecvUint8(&tmpu8), IsFalse());
169*ec63e07aSXin Li };
170*ec63e07aSXin Li auto b = [](Comms* comms) {
171*ec63e07aSXin Li // Send Int8 (but Uint8 expected).
172*ec63e07aSXin Li ASSERT_THAT(comms->SendInt8(-93), IsTrue());
173*ec63e07aSXin Li };
174*ec63e07aSXin Li HandleCommunication(a, b);
175*ec63e07aSXin Li }
176*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvString)177*ec63e07aSXin Li TEST(CommsTest, TestSendRecvString) {
178*ec63e07aSXin Li auto a = [](Comms* comms) {
179*ec63e07aSXin Li std::string tmps;
180*ec63e07aSXin Li ASSERT_THAT(comms->RecvString(&tmps), IsTrue());
181*ec63e07aSXin Li EXPECT_TRUE(tmps == NullTestString());
182*ec63e07aSXin Li EXPECT_THAT(tmps.size(), Eq(NullTestString().size()));
183*ec63e07aSXin Li };
184*ec63e07aSXin Li auto b = [](Comms* comms) {
185*ec63e07aSXin Li ASSERT_THAT(comms->SendString(std::string(NullTestString())), IsTrue());
186*ec63e07aSXin Li };
187*ec63e07aSXin Li HandleCommunication(a, b);
188*ec63e07aSXin Li }
189*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvArray)190*ec63e07aSXin Li TEST(CommsTest, TestSendRecvArray) {
191*ec63e07aSXin Li auto a = [](Comms* comms) {
192*ec63e07aSXin Li // Receive 1M bytes.
193*ec63e07aSXin Li std::vector<uint8_t> buffer;
194*ec63e07aSXin Li ASSERT_THAT(comms->RecvBytes(&buffer), IsTrue());
195*ec63e07aSXin Li EXPECT_THAT(buffer.size(), Eq(1024 * 1024));
196*ec63e07aSXin Li };
197*ec63e07aSXin Li auto b = [](Comms* comms) {
198*ec63e07aSXin Li // Send 1M bytes.
199*ec63e07aSXin Li std::vector<uint8_t> buffer(1024 * 1024);
200*ec63e07aSXin Li memset(buffer.data(), 0, buffer.size());
201*ec63e07aSXin Li ASSERT_THAT(comms->SendBytes(buffer), IsTrue());
202*ec63e07aSXin Li };
203*ec63e07aSXin Li HandleCommunication(a, b);
204*ec63e07aSXin Li }
205*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvFD)206*ec63e07aSXin Li TEST(CommsTest, TestSendRecvFD) {
207*ec63e07aSXin Li auto a = [](Comms* comms) {
208*ec63e07aSXin Li // Receive FD and test it.
209*ec63e07aSXin Li int fd = -1;
210*ec63e07aSXin Li ASSERT_THAT(comms->RecvFD(&fd), IsTrue());
211*ec63e07aSXin Li EXPECT_GE(fd, 0);
212*ec63e07aSXin Li EXPECT_NE(fcntl(fd, F_GETFD), -1);
213*ec63e07aSXin Li };
214*ec63e07aSXin Li auto b = [](Comms* comms) {
215*ec63e07aSXin Li // Send our STDERR to the thread.
216*ec63e07aSXin Li ASSERT_THAT(comms->SendFD(STDERR_FILENO), IsTrue());
217*ec63e07aSXin Li };
218*ec63e07aSXin Li HandleCommunication(a, b);
219*ec63e07aSXin Li }
220*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvEmptyTLV)221*ec63e07aSXin Li TEST(CommsTest, TestSendRecvEmptyTLV) {
222*ec63e07aSXin Li auto a = [](Comms* comms) {
223*ec63e07aSXin Li // Receive TLV without a value.
224*ec63e07aSXin Li uint32_t tag;
225*ec63e07aSXin Li std::vector<uint8_t> value;
226*ec63e07aSXin Li ASSERT_THAT(comms->RecvTLV(&tag, &value), IsTrue()); // NOLINT
227*ec63e07aSXin Li EXPECT_THAT(tag, Eq(0x00DEADBE));
228*ec63e07aSXin Li EXPECT_THAT(value.size(), Eq(0));
229*ec63e07aSXin Li };
230*ec63e07aSXin Li auto b = [](Comms* comms) {
231*ec63e07aSXin Li // Send TLV without a value.
232*ec63e07aSXin Li ASSERT_THAT(comms->SendTLV(0x00DEADBE, 0, nullptr), IsTrue());
233*ec63e07aSXin Li };
234*ec63e07aSXin Li HandleCommunication(a, b);
235*ec63e07aSXin Li }
236*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvEmptyTLV2)237*ec63e07aSXin Li TEST(CommsTest, TestSendRecvEmptyTLV2) {
238*ec63e07aSXin Li auto a = [](Comms* comms) {
239*ec63e07aSXin Li // Receive TLV without a value.
240*ec63e07aSXin Li uint32_t tag;
241*ec63e07aSXin Li std::vector<uint8_t> data;
242*ec63e07aSXin Li ASSERT_THAT(comms->RecvTLV(&tag, &data), IsTrue());
243*ec63e07aSXin Li EXPECT_THAT(tag, Eq(0x00DEADBE));
244*ec63e07aSXin Li EXPECT_THAT(data.size(), Eq(0));
245*ec63e07aSXin Li };
246*ec63e07aSXin Li auto b = [](Comms* comms) {
247*ec63e07aSXin Li // Send TLV without a value.
248*ec63e07aSXin Li ASSERT_THAT(comms->SendTLV(0x00DEADBE, 0, nullptr), IsTrue());
249*ec63e07aSXin Li };
250*ec63e07aSXin Li HandleCommunication(a, b);
251*ec63e07aSXin Li }
252*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvProto)253*ec63e07aSXin Li TEST(CommsTest, TestSendRecvProto) {
254*ec63e07aSXin Li auto a = [](Comms* comms) {
255*ec63e07aSXin Li // Receive a ProtoBuf.
256*ec63e07aSXin Li std::unique_ptr<CommsTestMsg> comms_msg(new CommsTestMsg());
257*ec63e07aSXin Li ASSERT_THAT(comms->RecvProtoBuf(comms_msg.get()), IsTrue());
258*ec63e07aSXin Li ASSERT_THAT(comms_msg->value_size(), Eq(1));
259*ec63e07aSXin Li EXPECT_THAT(comms_msg->value(0), Eq(kProtoStr));
260*ec63e07aSXin Li };
261*ec63e07aSXin Li auto b = [](Comms* comms) {
262*ec63e07aSXin Li // Send a ProtoBuf.
263*ec63e07aSXin Li std::unique_ptr<CommsTestMsg> comms_msg(new CommsTestMsg());
264*ec63e07aSXin Li comms_msg->add_value(kProtoStr);
265*ec63e07aSXin Li ASSERT_THAT(comms_msg->value_size(), Eq(1));
266*ec63e07aSXin Li ASSERT_THAT(comms->SendProtoBuf(*comms_msg), IsTrue());
267*ec63e07aSXin Li };
268*ec63e07aSXin Li HandleCommunication(a, b);
269*ec63e07aSXin Li }
270*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvStatusOK)271*ec63e07aSXin Li TEST(CommsTest, TestSendRecvStatusOK) {
272*ec63e07aSXin Li auto a = [](Comms* comms) {
273*ec63e07aSXin Li // Receive a good status.
274*ec63e07aSXin Li absl::Status status;
275*ec63e07aSXin Li ASSERT_THAT(comms->RecvStatus(&status), IsTrue());
276*ec63e07aSXin Li EXPECT_THAT(status, IsOk());
277*ec63e07aSXin Li };
278*ec63e07aSXin Li auto b = [](Comms* comms) {
279*ec63e07aSXin Li // Send a good status.
280*ec63e07aSXin Li ASSERT_THAT(comms->SendStatus(absl::OkStatus()), IsTrue());
281*ec63e07aSXin Li };
282*ec63e07aSXin Li HandleCommunication(a, b);
283*ec63e07aSXin Li }
284*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvStatusFailing)285*ec63e07aSXin Li TEST(CommsTest, TestSendRecvStatusFailing) {
286*ec63e07aSXin Li auto a = [](Comms* comms) {
287*ec63e07aSXin Li // Receive a failing status.
288*ec63e07aSXin Li absl::Status status;
289*ec63e07aSXin Li ASSERT_THAT(comms->RecvStatus(&status), IsTrue());
290*ec63e07aSXin Li EXPECT_THAT(status, Not(IsOk()));
291*ec63e07aSXin Li EXPECT_THAT(status, StatusIs(absl::StatusCode::kInternal, "something odd"));
292*ec63e07aSXin Li };
293*ec63e07aSXin Li auto b = [](Comms* comms) {
294*ec63e07aSXin Li // Send a failing status.
295*ec63e07aSXin Li ASSERT_THAT(comms->SendStatus(
296*ec63e07aSXin Li absl::Status{absl::StatusCode::kInternal, "something odd"}),
297*ec63e07aSXin Li IsTrue());
298*ec63e07aSXin Li };
299*ec63e07aSXin Li HandleCommunication(a, b);
300*ec63e07aSXin Li }
301*ec63e07aSXin Li
TEST(CommsTest,TestUsesDistinctBuffers)302*ec63e07aSXin Li TEST(CommsTest, TestUsesDistinctBuffers) {
303*ec63e07aSXin Li auto a = [](Comms* comms) {
304*ec63e07aSXin Li // Receive 1M bytes.
305*ec63e07aSXin Li std::vector<uint8_t> buffer1, buffer2;
306*ec63e07aSXin Li ASSERT_THAT(comms->RecvBytes(&buffer1), IsTrue()); // NOLINT
307*ec63e07aSXin Li EXPECT_THAT(buffer1.size(), Eq(1024 * 1024));
308*ec63e07aSXin Li
309*ec63e07aSXin Li ASSERT_THAT(comms->RecvBytes(&buffer2), IsTrue()); // NOLINT
310*ec63e07aSXin Li EXPECT_THAT(buffer2.size(), Eq(1024 * 1024));
311*ec63e07aSXin Li
312*ec63e07aSXin Li // Make sure we can access the buffer (memory was not free'd).
313*ec63e07aSXin Li // Probably only useful when running with ASAN/MSAN.
314*ec63e07aSXin Li EXPECT_THAT(buffer1[1024 * 1024 - 1], Eq(buffer1[1024 * 1024 - 1]));
315*ec63e07aSXin Li EXPECT_THAT(buffer2[1024 * 1024 - 1], Eq(buffer2[1024 * 1024 - 1]));
316*ec63e07aSXin Li EXPECT_NE(buffer1.data(), buffer2.data());
317*ec63e07aSXin Li };
318*ec63e07aSXin Li auto b = [](Comms* comms) {
319*ec63e07aSXin Li // Send 1M bytes.
320*ec63e07aSXin Li absl::FixedArray<uint8_t> buf(1024 * 1024);
321*ec63e07aSXin Li memset(buf.data(), 0, buf.size());
322*ec63e07aSXin Li ASSERT_THAT(comms->SendBytes(buf.data(), buf.size()), IsTrue());
323*ec63e07aSXin Li ASSERT_THAT(comms->SendBytes(buf.data(), buf.size()), IsTrue());
324*ec63e07aSXin Li };
325*ec63e07aSXin Li HandleCommunication(a, b);
326*ec63e07aSXin Li }
327*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvCredentials)328*ec63e07aSXin Li TEST(CommsTest, TestSendRecvCredentials) {
329*ec63e07aSXin Li auto a = [](Comms* comms) {
330*ec63e07aSXin Li // Check credentials.
331*ec63e07aSXin Li pid_t pid;
332*ec63e07aSXin Li uid_t uid;
333*ec63e07aSXin Li gid_t gid;
334*ec63e07aSXin Li ASSERT_THAT(comms->RecvCreds(&pid, &uid, &gid), IsTrue());
335*ec63e07aSXin Li EXPECT_THAT(pid, Eq(getpid()));
336*ec63e07aSXin Li EXPECT_THAT(uid, Eq(getuid()));
337*ec63e07aSXin Li EXPECT_THAT(gid, Eq(getgid()));
338*ec63e07aSXin Li };
339*ec63e07aSXin Li auto b = [](Comms* comms) {
340*ec63e07aSXin Li // Nothing to do here.
341*ec63e07aSXin Li };
342*ec63e07aSXin Li HandleCommunication(a, b);
343*ec63e07aSXin Li }
344*ec63e07aSXin Li
TEST(CommsTest,TestSendTooMuchData)345*ec63e07aSXin Li TEST(CommsTest, TestSendTooMuchData) {
346*ec63e07aSXin Li auto a = [](Comms* comms) {
347*ec63e07aSXin Li // Nothing to do here.
348*ec63e07aSXin Li };
349*ec63e07aSXin Li auto b = [](Comms* comms) {
350*ec63e07aSXin Li // Send too much data.
351*ec63e07aSXin Li ASSERT_THAT(comms->SendBytes(nullptr, comms->GetMaxMsgSize() + 1),
352*ec63e07aSXin Li IsFalse());
353*ec63e07aSXin Li };
354*ec63e07aSXin Li HandleCommunication(a, b);
355*ec63e07aSXin Li }
356*ec63e07aSXin Li
TEST(CommsTest,TestSendRecvBytes)357*ec63e07aSXin Li TEST(CommsTest, TestSendRecvBytes) {
358*ec63e07aSXin Li auto a = [](Comms* comms) {
359*ec63e07aSXin Li std::vector<uint8_t> buffer;
360*ec63e07aSXin Li ASSERT_THAT(comms->RecvBytes(&buffer), IsTrue());
361*ec63e07aSXin Li ASSERT_THAT(comms->SendBytes(buffer), IsTrue());
362*ec63e07aSXin Li };
363*ec63e07aSXin Li auto b = [](Comms* comms) {
364*ec63e07aSXin Li const std::vector<uint8_t> request = {0, 1, 2, 3, 7};
365*ec63e07aSXin Li ASSERT_THAT(comms->SendBytes(request), IsTrue());
366*ec63e07aSXin Li
367*ec63e07aSXin Li std::vector<uint8_t> response;
368*ec63e07aSXin Li ASSERT_THAT(comms->RecvBytes(&response), IsTrue());
369*ec63e07aSXin Li EXPECT_THAT(request, Eq(response));
370*ec63e07aSXin Li };
371*ec63e07aSXin Li HandleCommunication(a, b);
372*ec63e07aSXin Li }
373*ec63e07aSXin Li
374*ec63e07aSXin Li } // namespace sandbox2
375