1 /*
2  *  Copyright (c) 2018-present, Facebook, Inc.
3  *  All rights reserved.
4  *
5  *  This source code is licensed under the BSD-style license found in the
6  *  LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <folly/portability/GMock.h>
10 #include <folly/portability/GTest.h>
11 
12 #include <fizz/server/AsyncFizzServer.h>
13 
14 #include <fizz/extensions/tokenbinding/Types.h>
15 #include <fizz/server/test/Mocks.h>
16 #include <folly/io/async/test/MockAsyncTransport.h>
17 
18 namespace fizz {
19 namespace server {
20 namespace test {
21 
22 using namespace fizz::extensions;
23 using namespace folly;
24 using namespace folly::test;
25 using namespace testing;
26 
27 template <typename... Args>
actions(Args &&...act)28 AsyncActions actions(Args&&... act) {
29   return fizz::server::detail::actions(std::forward<Args>(act)...);
30 }
31 
32 class MockServerStateMachineInstance : public MockServerStateMachine {
33  public:
MockServerStateMachineInstance()34   MockServerStateMachineInstance() {
35     instance = this;
36   }
37   static MockServerStateMachineInstance* instance;
38 };
39 MockServerStateMachineInstance* MockServerStateMachineInstance::instance;
40 
41 class AsyncFizzServerTest : public Test {
42  public:
SetUp()43   void SetUp() override {
44     context_ = std::make_shared<FizzServerContext>();
45     socket_ = new MockAsyncTransport();
46     auto transport = AsyncTransportWrapper::UniquePtr(socket_);
47     server_.reset(new AsyncFizzServerT<MockServerStateMachineInstance>(
48         std::move(transport),
49         context_,
50         std::make_shared<MockServerExtensions>()));
51     machine_ = MockServerStateMachineInstance::instance;
52     ON_CALL(*socket_, good()).WillByDefault(Return(true));
53     ON_CALL(readCallback_, isBufferMovable_()).WillByDefault(Return(true));
54   }
55 
56  protected:
expectTransportReadCallback()57   void expectTransportReadCallback() {
58     EXPECT_CALL(*socket_, setReadCB(_))
59         .WillRepeatedly(SaveArg<0>(&socketReadCallback_));
60   }
61 
expectAppClose()62   void expectAppClose() {
63     EXPECT_CALL(*machine_, _processAppClose(_))
64         .WillOnce(InvokeWithoutArgs([]() {
65           WriteToSocket write;
66           TLSContent record;
67           record.contentType = ContentType::alert;
68           record.encryptionLevel = EncryptionLevel::Handshake;
69           record.data = IOBuf::copyBuffer("closenotify");
70           write.contents.emplace_back(std::move(record));
71           return detail::actions(
72               MutateState(
73                   [](State& newState) { newState.state() = StateEnum::Error; }),
74               std::move(write));
75         }));
76   }
77 
expectAppCloseImmediate()78   void expectAppCloseImmediate() {
79     EXPECT_CALL(*machine_, _processAppCloseImmediate(_))
80         .WillOnce(InvokeWithoutArgs([]() {
81           WriteToSocket write;
82           TLSContent record;
83           record.contentType = ContentType::alert;
84           record.encryptionLevel = EncryptionLevel::Handshake;
85           record.data = IOBuf::copyBuffer("closenotify");
86           write.contents.emplace_back(std::move(record));
87           return detail::actions(
88               MutateState(
89                   [](State& newState) { newState.state() = StateEnum::Error; }),
90               std::move(write));
91         }));
92   }
93 
accept()94   void accept() {
95     expectTransportReadCallback();
96     EXPECT_CALL(*socket_, getEventBase()).WillOnce(Return(&evb_));
97     EXPECT_CALL(*machine_, _processAccept(_, &evb_, _, _))
98         .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
99     server_->accept(&handshakeCallback_);
100   }
101 
fullHandshakeSuccess(std::shared_ptr<const Cert> clientCert=nullptr,std::shared_ptr<const Cert> serverCert=nullptr)102   void fullHandshakeSuccess(
103       std::shared_ptr<const Cert> clientCert = nullptr,
104       std::shared_ptr<const Cert> serverCert = nullptr) {
105     EXPECT_CALL(*machine_, _processSocketData(_, _, _))
106         .WillOnce(InvokeWithoutArgs([clientCert,
107                                      serverCert,
108                                      cipher = negotiatedCipher_,
109                                      protocolVersion = protocolVersion_]() {
110           MutateState addExporterToState([=](State& newState) {
111             auto exporterMaster =
112                 folly::IOBuf::copyBuffer("12345678901234567890123456789012");
113             newState.exporterMasterSecret() = std::move(exporterMaster);
114             newState.cipher() = cipher;
115             newState.version() = protocolVersion;
116             newState.clientCert() = clientCert;
117             newState.serverCert() = serverCert;
118           });
119           return actions(
120               std::move(addExporterToState),
121               ReportHandshakeSuccess(),
122               WaitForData());
123         }));
124     socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
125   }
126 
completeHandshake()127   void completeHandshake() {
128     accept();
129     EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
130     fullHandshakeSuccess();
131   }
132 
133   AsyncFizzServerT<MockServerStateMachineInstance>::UniquePtr server_;
134   std::shared_ptr<FizzServerContext> context_;
135   MockAsyncTransport* socket_;
136   MockServerStateMachineInstance* machine_;
137   AsyncTransportWrapper::ReadCallback* socketReadCallback_;
138   MockHandshakeCallbackT<MockServerStateMachineInstance> handshakeCallback_;
139   MockReadCallback readCallback_;
140   MockWriteCallback writeCallback_;
141   EventBase evb_;
142   CipherSuite negotiatedCipher_ = CipherSuite::TLS_AES_128_GCM_SHA256;
143   ProtocolVersion protocolVersion_ = ProtocolVersion::tls_1_3;
144 };
145 
146 MATCHER_P(BufMatches, expected, "") {
147   folly::IOBufEqualTo eq;
148   return eq(*arg, *expected);
149 }
150 
TEST_F(AsyncFizzServerTest,TestAccept)151 TEST_F(AsyncFizzServerTest, TestAccept) {
152   accept();
153 }
154 
TEST_F(AsyncFizzServerTest,TestReadSingle)155 TEST_F(AsyncFizzServerTest, TestReadSingle) {
156   accept();
157   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
158       .WillOnce(InvokeWithoutArgs([]() { return actions(WaitForData()); }));
159   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
160 }
161 
TEST_F(AsyncFizzServerTest,TestReadMulti)162 TEST_F(AsyncFizzServerTest, TestReadMulti) {
163   accept();
164   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
165       .WillOnce(InvokeWithoutArgs([]() { return actions(); }))
166       .WillOnce(InvokeWithoutArgs([]() { return actions(WaitForData()); }));
167   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
168 }
169 
TEST_F(AsyncFizzServerTest,TestWrite)170 TEST_F(AsyncFizzServerTest, TestWrite) {
171   accept();
172   EXPECT_CALL(*machine_, _processAppWrite(_, _))
173       .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
174   server_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
175 }
176 
TEST_F(AsyncFizzServerTest,TestWriteMulti)177 TEST_F(AsyncFizzServerTest, TestWriteMulti) {
178   accept();
179   EXPECT_CALL(*machine_, _processAppWrite(_, _))
180       .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
181   server_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
182   EXPECT_CALL(*machine_, _processAppWrite(_, _))
183       .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
184   server_->writeChain(nullptr, IOBuf::copyBuffer("HTTP POST"));
185 }
186 
TEST_F(AsyncFizzServerTest,TestWriteErrorState)187 TEST_F(AsyncFizzServerTest, TestWriteErrorState) {
188   accept();
189   ON_CALL(*socket_, error()).WillByDefault(Return(true));
190   EXPECT_CALL(writeCallback_, writeErr_(0, _));
191   server_->writeChain(&writeCallback_, IOBuf::copyBuffer("test"));
192 }
193 
TEST_F(AsyncFizzServerTest,TestWriteNotGoodState)194 TEST_F(AsyncFizzServerTest, TestWriteNotGoodState) {
195   accept();
196   ON_CALL(*socket_, good()).WillByDefault(Return(false));
197   EXPECT_CALL(writeCallback_, writeErr_(0, _));
198   server_->writeChain(&writeCallback_, IOBuf::copyBuffer("test"));
199 }
200 
TEST_F(AsyncFizzServerTest,TestHandshake)201 TEST_F(AsyncFizzServerTest, TestHandshake) {
202   completeHandshake();
203 }
204 
TEST_F(AsyncFizzServerTest,TestExporterAPISimple)205 TEST_F(AsyncFizzServerTest, TestExporterAPISimple) {
206   completeHandshake();
207   server_->getEkm(kTokenBindingExporterLabel, nullptr, 32);
208 }
209 
TEST_F(AsyncFizzServerTest,TestExporterAPIIncompleteHandshake)210 TEST_F(AsyncFizzServerTest, TestExporterAPIIncompleteHandshake) {
211   EXPECT_THROW(
212       server_->getEkm(kTokenBindingExporterLabel, nullptr, 32),
213       std::runtime_error);
214 }
215 
TEST_F(AsyncFizzServerTest,TestHandshakeError)216 TEST_F(AsyncFizzServerTest, TestHandshakeError) {
217   accept();
218   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
219       .WillOnce(InvokeWithoutArgs(
220           []() { return actions(ReportError("unit test"), WaitForData()); }));
221   EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
222   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
223 }
224 
TEST_F(AsyncFizzServerTest,TestDeliverAppData)225 TEST_F(AsyncFizzServerTest, TestDeliverAppData) {
226   completeHandshake();
227   server_->setReadCB(&readCallback_);
228   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
229       .WillOnce(InvokeWithoutArgs([]() {
230         return actions(DeliverAppData{IOBuf::copyBuffer("HI")}, WaitForData());
231       }));
232   EXPECT_CALL(readCallback_, readBufferAvailable_(_));
233   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
234 }
235 
TEST_F(AsyncFizzServerTest,TestSendTicketWithAppToken)236 TEST_F(AsyncFizzServerTest, TestSendTicketWithAppToken) {
237   completeHandshake();
238   EXPECT_CALL(*machine_, _processWriteNewSessionTicket(_, _))
239       .WillOnce(InvokeWithoutArgs([]() {
240         WriteToSocket write;
241         TLSContent record;
242         record.contentType = ContentType::handshake;
243         record.encryptionLevel = EncryptionLevel::AppTraffic;
244         record.data = IOBuf::copyBuffer("XYZ");
245         write.contents.emplace_back(std::move(record));
246         return actions(std::move(write));
247       }));
248   EXPECT_CALL(*socket_, writeChain(_, _, _));
249   server_->sendTicketWithAppToken(IOBuf::copyBuffer("testAppToken"));
250 }
251 
TEST_F(AsyncFizzServerTest,TestWriteToSocket)252 TEST_F(AsyncFizzServerTest, TestWriteToSocket) {
253   completeHandshake();
254   server_->setReadCB(&readCallback_);
255   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
256       .WillOnce(InvokeWithoutArgs([]() {
257         WriteToSocket write;
258         TLSContent record;
259         record.contentType = ContentType::application_data;
260         record.encryptionLevel = EncryptionLevel::AppTraffic;
261         record.data = IOBuf::copyBuffer("XYZ");
262         write.contents.emplace_back(std::move(record));
263         return actions(std::move(write), WaitForData());
264       }));
265   EXPECT_CALL(*socket_, writeChain(_, _, _));
266   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
267 }
268 
TEST_F(AsyncFizzServerTest,TestMutateState)269 TEST_F(AsyncFizzServerTest, TestMutateState) {
270   completeHandshake();
271   server_->setReadCB(&readCallback_);
272   uint32_t numTimesRun = 0;
273   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
274       .WillOnce(InvokeWithoutArgs([&numTimesRun]() {
275         return actions(
276             MutateState([&numTimesRun](State& newState) {
277               numTimesRun++;
278               newState.state() = StateEnum::Error;
279             }),
280             WaitForData());
281       }));
282   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
283   EXPECT_EQ(server_->getState().state(), StateEnum::Error);
284   EXPECT_EQ(numTimesRun, 1);
285 }
286 
TEST_F(AsyncFizzServerTest,TestAttemptVersionFallback)287 TEST_F(AsyncFizzServerTest, TestAttemptVersionFallback) {
288   accept();
289   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
290       .WillOnce(InvokeWithoutArgs([]() {
291         return actions(
292             MutateState(
293                 [](State& newState) { newState.state() = StateEnum::Error; }),
294             AttemptVersionFallback{IOBuf::copyBuffer("ClientHello")});
295       }));
296   EXPECT_CALL(handshakeCallback_, _fizzHandshakeAttemptFallback(_))
297       .WillOnce(Invoke([&](std::unique_ptr<IOBuf>& clientHello) {
298         // The mock machine does not move the read buffer so there will be a 2nd
299         // ClientHello.
300         EXPECT_TRUE(IOBufEqualTo()(
301             clientHello, IOBuf::copyBuffer("ClientHelloClientHello")));
302         server_.reset();
303       }));
304   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
305 }
306 
TEST_F(AsyncFizzServerTest,TestDeleteAsyncEvent)307 TEST_F(AsyncFizzServerTest, TestDeleteAsyncEvent) {
308   accept();
309   Promise<Actions> p1;
310   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
311       .WillOnce(
312           InvokeWithoutArgs([&p1]() { return AsyncActions(p1.getFuture()); }));
313   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
314   server_.reset();
315   Promise<Actions> p2;
316   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
317       .WillOnce(
318           InvokeWithoutArgs([&p2]() { return AsyncActions(p2.getFuture()); }));
319   p1.setValue(detail::actions());
320   p2.setValue(detail::actions(WaitForData()));
321 }
322 
TEST_F(AsyncFizzServerTest,TestCloseHandshake)323 TEST_F(AsyncFizzServerTest, TestCloseHandshake) {
324   accept();
325   expectAppCloseImmediate();
326   EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
327   EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
328   server_->closeNow();
329 }
330 
TEST_F(AsyncFizzServerTest,TestTLSShutdown)331 TEST_F(AsyncFizzServerTest, TestTLSShutdown) {
332   accept();
333   expectAppClose();
334   EXPECT_CALL(*socket_, close()).Times(0);
335   server_->tlsShutdown();
336 }
337 
TEST_F(AsyncFizzServerTest,TestCloseNowInFlightAction)338 TEST_F(AsyncFizzServerTest, TestCloseNowInFlightAction) {
339   completeHandshake();
340   server_->setReadCB(&readCallback_);
341   Promise<Actions> p;
342   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
343       .WillOnce(
344           InvokeWithoutArgs([&p]() { return AsyncActions(p.getFuture()); }));
345   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
346   server_->writeChain(&writeCallback_, IOBuf::copyBuffer("queued write"));
347   EXPECT_CALL(writeCallback_, writeErr_(0, _));
348   EXPECT_CALL(readCallback_, readEOF_());
349   EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
350   server_->closeNow();
351   p.setValue(detail::actions(WaitForData()));
352 }
353 
TEST_F(AsyncFizzServerTest,TestCloseInFlightAction)354 TEST_F(AsyncFizzServerTest, TestCloseInFlightAction) {
355   completeHandshake();
356   server_->setReadCB(&readCallback_);
357   Promise<Actions> p;
358   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
359       .WillOnce(
360           InvokeWithoutArgs([&p]() { return AsyncActions(p.getFuture()); }));
361   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
362   server_->writeChain(&writeCallback_, IOBuf::copyBuffer("queued write"));
363   server_->close();
364 
365   EXPECT_CALL(*machine_, _processAppWrite(_, _))
366       .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
367   expectAppCloseImmediate();
368   p.setValue(detail::actions(WaitForData()));
369 }
370 
TEST_F(AsyncFizzServerTest,TestIsDetachable)371 TEST_F(AsyncFizzServerTest, TestIsDetachable) {
372   completeHandshake();
373   AsyncTransportWrapper::ReadCallback* readCb = socketReadCallback_;
374   ON_CALL(*socket_, isDetachable()).WillByDefault(Return(false));
375   EXPECT_FALSE(server_->isDetachable());
376   ON_CALL(*socket_, isDetachable()).WillByDefault(Return(true));
377   EXPECT_TRUE(server_->isDetachable());
378   Promise<Actions> p;
379 
380   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
381       .WillOnce(
382           InvokeWithoutArgs([&p]() { return AsyncActions(p.getFuture()); }));
383   socket_->setReadCB(readCb);
384   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
385   EXPECT_FALSE(server_->isDetachable());
386   p.setValue(detail::actions(WaitForData()));
387   EXPECT_TRUE(server_->isDetachable());
388 }
389 
TEST_F(AsyncFizzServerTest,TestConnecting)390 TEST_F(AsyncFizzServerTest, TestConnecting) {
391   ON_CALL(*socket_, connecting()).WillByDefault(Return(true));
392   EXPECT_TRUE(server_->connecting());
393   ON_CALL(*socket_, connecting()).WillByDefault(Return(false));
394   accept();
395   EXPECT_TRUE(server_->connecting());
396   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
397       .WillOnce(InvokeWithoutArgs(
398           []() { return actions(ReportHandshakeSuccess(), WaitForData()); }));
399   EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
400   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
401   EXPECT_FALSE(server_->connecting());
402 }
403 
TEST_F(AsyncFizzServerTest,TestGoodSocket)404 TEST_F(AsyncFizzServerTest, TestGoodSocket) {
405   accept();
406   ON_CALL(*socket_, good()).WillByDefault(Return(true));
407   EXPECT_TRUE(server_->good());
408   ON_CALL(*socket_, good()).WillByDefault(Return(false));
409   EXPECT_FALSE(server_->good());
410 }
411 
TEST_F(AsyncFizzServerTest,TestGoodState)412 TEST_F(AsyncFizzServerTest, TestGoodState) {
413   completeHandshake();
414   ON_CALL(*socket_, good()).WillByDefault(Return(true));
415   EXPECT_TRUE(server_->good());
416   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
417       .WillOnce(InvokeWithoutArgs([]() {
418         return actions(MutateState(
419             [](State& newState) { newState.state() = StateEnum::Error; }));
420       }));
421   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
422   EXPECT_FALSE(server_->good());
423 }
424 
TEST_F(AsyncFizzServerTest,TestEarlySuccess)425 TEST_F(AsyncFizzServerTest, TestEarlySuccess) {
426   accept();
427   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
428       .WillOnce(InvokeWithoutArgs([]() {
429         return actions(ReportEarlyHandshakeSuccess(), WaitForData());
430       }));
431   EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
432   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
433 
434   fullHandshakeSuccess();
435 }
436 
TEST_F(AsyncFizzServerTest,TestErrorStopsActions)437 TEST_F(AsyncFizzServerTest, TestErrorStopsActions) {
438   completeHandshake();
439   server_->setReadCB(&readCallback_);
440   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
441       .WillOnce(InvokeWithoutArgs([]() {
442         return actions(
443             MutateState(
444                 [](State& newState) { newState.state() = StateEnum::Error; }),
445             ReportError("unit test"));
446       }));
447   EXPECT_FALSE(server_->error());
448   EXPECT_TRUE(server_->good());
449   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
450   EXPECT_TRUE(server_->error());
451   EXPECT_FALSE(server_->good());
452 }
453 
TEST_F(AsyncFizzServerTest,TestTransportError)454 TEST_F(AsyncFizzServerTest, TestTransportError) {
455   completeHandshake();
456   server_->setReadCB(&readCallback_);
457   EXPECT_CALL(*machine_, _processSocketData(_, _, _)).Times(0);
458   EXPECT_FALSE(server_->error());
459   EXPECT_TRUE(server_->good());
460   ON_CALL(*socket_, error()).WillByDefault(Return(true));
461   AsyncSocketException ase(AsyncSocketException::UNKNOWN, "unit test");
462   socketReadCallback_->readErr(ase);
463   EXPECT_TRUE(server_->error());
464   EXPECT_FALSE(server_->good());
465   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
466   EXPECT_TRUE(server_->error());
467   EXPECT_FALSE(server_->good());
468 }
469 
TEST_F(AsyncFizzServerTest,TestTransportEof)470 TEST_F(AsyncFizzServerTest, TestTransportEof) {
471   completeHandshake();
472   server_->setReadCB(&readCallback_);
473   EXPECT_CALL(*machine_, _processSocketData(_, _, _)).Times(0);
474   EXPECT_FALSE(server_->error());
475   EXPECT_TRUE(server_->good());
476   ON_CALL(*socket_, good()).WillByDefault(Return(false));
477   socketReadCallback_->readEOF();
478   EXPECT_FALSE(server_->error());
479   EXPECT_FALSE(server_->good());
480   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
481   EXPECT_FALSE(server_->error());
482   EXPECT_FALSE(server_->good());
483 }
484 
TEST_F(AsyncFizzServerTest,TestGetCertsNone)485 TEST_F(AsyncFizzServerTest, TestGetCertsNone) {
486   completeHandshake();
487   EXPECT_EQ(server_->getSelfCertificate(), nullptr);
488   EXPECT_EQ(server_->getPeerCertificate(), nullptr);
489 }
490 
TEST_F(AsyncFizzServerTest,TestGetCerts)491 TEST_F(AsyncFizzServerTest, TestGetCerts) {
492   auto clientCert = std::make_shared<MockCert>();
493   auto serverCert = std::make_shared<MockCert>();
494   accept();
495   EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
496   fullHandshakeSuccess(clientCert, serverCert);
497   EXPECT_NE(server_->getSelfCertificate(), nullptr);
498   EXPECT_NE(server_->getPeerCertificate(), nullptr);
499 }
500 
TEST_F(AsyncFizzServerTest,TestTransportNotGoodOnSuccess)501 TEST_F(AsyncFizzServerTest, TestTransportNotGoodOnSuccess) {
502   accept();
503   EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
504   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
505       .WillOnce(InvokeWithoutArgs([&]() {
506         // Make the socket return not good
507         EXPECT_CALL(*socket_, good()).WillOnce(Return(false));
508         return actions(ReportHandshakeSuccess());
509       }));
510   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
511   EXPECT_FALSE(server_->good());
512 }
513 
TEST_F(AsyncFizzServerTest,TestTransportNotGoodOnEarlySuccess)514 TEST_F(AsyncFizzServerTest, TestTransportNotGoodOnEarlySuccess) {
515   accept();
516   EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
517   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
518       .WillOnce(InvokeWithoutArgs([&]() {
519         // Make the socket return not good
520         EXPECT_CALL(*socket_, good()).WillOnce(Return(false));
521         return actions(ReportEarlyHandshakeSuccess());
522       }));
523   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
524   EXPECT_FALSE(server_->good());
525 }
526 
TEST_F(AsyncFizzServerTest,TestRemoteClosed)527 TEST_F(AsyncFizzServerTest, TestRemoteClosed) {
528   completeHandshake();
529   server_->setReadCB(&readCallback_);
530   EXPECT_CALL(readCallback_, readEOF_());
531   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
532       .WillOnce(InvokeWithoutArgs([]() {
533         return actions(
534             MutateState([](State& s) { s.state() = StateEnum::Closed; }),
535             EndOfData());
536       }));
537   EXPECT_CALL(*socket_, closeNow());
538   EXPECT_TRUE(server_->good());
539   socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
540   EXPECT_FALSE(server_->good());
541 }
542 
TEST_F(AsyncFizzServerTest,TestHandshakeRecordAlignedReads)543 TEST_F(AsyncFizzServerTest, TestHandshakeRecordAlignedReads) {
544   server_->setHandshakeRecordAlignedReads(true);
545 
546   accept();
547 
548   void* buf;
549   size_t len;
550   socketReadCallback_->getReadBuffer(&buf, &len);
551 
552   // Handshake record aligned reads begin with a read of 5 bytes for the
553   // record header.
554   EXPECT_EQ(len, 5);
555 
556   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
557       .WillOnce(InvokeWithoutArgs([] { return actions(WaitForData{10}); }));
558   socketReadCallback_->readDataAvailable(5);
559 
560   socketReadCallback_->getReadBuffer(&buf, &len);
561   EXPECT_EQ(len, 10);
562 
563   EXPECT_CALL(*machine_, _processSocketData(_, _, _))
564       .WillOnce(Invoke([](auto&&, auto&& queue, auto&&) {
565         queue.move();
566         return actions(WaitForData{5});
567       }));
568   socketReadCallback_->readDataAvailable(10);
569 
570   // Handshake successs event should have now transitioned the socket to
571   // not perform record aligned reads, so subsequent allocations should be
572   // larger
573   fullHandshakeSuccess();
574   socketReadCallback_->getReadBuffer(&buf, &len);
575 
576   // Not caring about record alignment, we should be able to get a buffer of
577   // at least AsyncFizzBase::kMinReadSize
578   EXPECT_GE(len, 1460);
579 }
580 
581 } // namespace test
582 } // namespace server
583 } // namespace fizz
584