proxygen
AsyncFizzClientTest.cpp
Go to the documentation of this file.
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 <gmock/gmock.h>
10 #include <gtest/gtest.h>
11 
13 
14 #include <fizz/client/test/Mocks.h>
19 
20 namespace fizz {
21 namespace client {
22 namespace test {
23 
24 using namespace fizz::test;
25 using namespace folly;
26 using namespace folly::test;
27 using namespace testing;
28 
30  public:
32  instance = this;
33  }
35 };
37 
39  public:
40  MOCK_METHOD0(_connectSuccess, void());
41  MOCK_METHOD1(_connectErr, void(const AsyncSocketException&));
42 
43  void connectSuccess() noexcept override {
44  _connectSuccess();
45  }
46 
47  void connectErr(const AsyncSocketException& ex) noexcept override {
48  _connectErr(ex);
49  }
50 };
51 
52 class AsyncFizzClientTest : public Test {
53  public:
54  void SetUp() override {
55  context_ = std::make_shared<FizzClientContext>();
56  context_->setSendEarlyData(true);
57  mockPskCache_ = std::make_shared<MockPskCache>();
58  context_->setPskCache(mockPskCache_);
60  auto transport = AsyncTransportWrapper::UniquePtr(socket_);
62  std::move(transport), context_));
64  ON_CALL(*socket_, good()).WillByDefault(Return(true));
65  ON_CALL(readCallback_, isBufferMovable_()).WillByDefault(Return(true));
66  }
67 
68  protected:
70  EXPECT_CALL(*socket_, setReadCB(_))
71  .WillRepeatedly(SaveArg<0>(&socketReadCallback_));
72  }
73 
74  void expectAppClose() {
75  EXPECT_CALL(*machine_, _processAppClose(_))
76  .WillOnce(InvokeWithoutArgs([]() {
77  TLSContent record;
79  record.data = IOBuf::copyBuffer("closenotify");
82  write.contents.emplace_back(std::move(record));
83  return detail::actions(
84  [](State& newState) { newState.state() = StateEnum::Error; },
85  std::move(write));
86  }));
87  }
88 
89  void connect() {
90  expectTransportReadCallback();
91  EXPECT_CALL(*machine_, _processConnect(_, _, _, _, _, _))
92  .WillOnce(InvokeWithoutArgs([]() { return Actions(); }));
93  const auto sni = std::string("www.example.com");
94  client_->connect(&handshakeCallback_, nullptr, sni, pskIdentity_);
95  }
96 
98  bool acceptEarlyData,
99  std::string alpn = "h2",
100  std::shared_ptr<const Cert> clientCert = nullptr,
101  std::shared_ptr<const Cert> serverCert = nullptr,
102  bool pskResumed = false) {
103  EXPECT_CALL(*machine_, _processSocketData(_, _))
104  .WillOnce(InvokeWithoutArgs([=]() {
105  auto addToState = [=](State& newState) {
106  newState.exporterMasterSecret() =
107  folly::IOBuf::copyBuffer("12345678901234567890123456789012");
108  newState.cipher() = CipherSuite::TLS_AES_128_GCM_SHA256;
109  newState.version() = ProtocolVersion::tls_1_3;
110  if (alpn.empty()) {
111  newState.alpn() = none;
112  } else {
113  newState.alpn() = alpn;
114  }
115  newState.clientCert() = clientCert;
116  newState.serverCert() = serverCert;
117 
118  if (acceptEarlyData || pskResumed) {
119  newState.pskMode() = PskKeyExchangeMode::psk_ke;
120  newState.pskType() = PskType::Resumption;
121  }
122  };
123  ReportHandshakeSuccess reportSuccess;
124  reportSuccess.earlyDataAccepted = acceptEarlyData;
125  return detail::actions(
126  std::move(addToState), std::move(reportSuccess), WaitForData());
127  }));
128  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ServerData"));
129  }
130 
132  connect();
133  EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
134  fullHandshakeSuccess(false);
135  }
136 
141  params.alpn = "h2";
142  return params;
143  }
144 
146  connect();
147  EXPECT_CALL(*machine_, _processSocketData(_, _))
148  .WillOnce(InvokeWithoutArgs([&params]() {
149  auto addParamsToState =
150  [params = std::move(params)](State& newState) mutable {
151  newState.earlyDataParams() = std::move(params);
152  };
153  ReportEarlyHandshakeSuccess reportSuccess;
154  reportSuccess.maxEarlyDataSize = 1000;
155  return detail::actions(
156  std::move(addParamsToState),
157  std::move(reportSuccess),
158  WaitForData());
159  }));
160  EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
161  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ServerData"));
162  EXPECT_FALSE(client_->isReplaySafe());
163  }
164 
166  std::shared_ptr<FizzClientContext> context_;
167  std::shared_ptr<MockPskCache> mockPskCache_;
176  folly::Optional<std::string> pskIdentity_{"pskIdentity"};
177 };
178 
179 MATCHER_P(BufMatches, expected, "") {
181  return eq(*arg, *expected);
182 }
183 
185  connect();
186 }
187 
188 TEST_F(AsyncFizzClientTest, TestReadSingle) {
189  connect();
190  EXPECT_CALL(*machine_, _processSocketData(_, _))
191  .WillOnce(
192  InvokeWithoutArgs([]() { return detail::actions(WaitForData()); }));
193  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
194 }
195 
196 TEST_F(AsyncFizzClientTest, TestReadMulti) {
197  connect();
198  EXPECT_CALL(*machine_, _processSocketData(_, _))
199  .WillOnce(InvokeWithoutArgs([]() { return detail::actions(); }))
200  .WillOnce(
201  InvokeWithoutArgs([]() { return detail::actions(WaitForData()); }));
202  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
203 }
204 
206  connect();
207  EXPECT_CALL(*machine_, _processAppWrite(_, _))
208  .WillOnce(InvokeWithoutArgs([]() { return detail::actions(); }));
209  client_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
210 }
211 
212 TEST_F(AsyncFizzClientTest, TestWriteMulti) {
213  connect();
214  EXPECT_CALL(*machine_, _processAppWrite(_, _))
215  .WillOnce(InvokeWithoutArgs([]() { return detail::actions(); }));
216  client_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
217  EXPECT_CALL(*machine_, _processAppWrite(_, _))
218  .WillOnce(InvokeWithoutArgs([]() { return detail::actions(); }));
219  client_->writeChain(nullptr, IOBuf::copyBuffer("HTTP POST"));
220 }
221 
222 TEST_F(AsyncFizzClientTest, TestWriteErrorState) {
223  connect();
224  ON_CALL(*socket_, error()).WillByDefault(Return(true));
225  EXPECT_CALL(writeCallback_, writeErr_(0, _));
226  client_->writeChain(&writeCallback_, IOBuf::copyBuffer("test"));
227 }
228 
229 TEST_F(AsyncFizzClientTest, TestHandshake) {
230  completeHandshake();
231  EXPECT_TRUE(client_->isReplaySafe());
232 }
233 
234 TEST_F(AsyncFizzClientTest, TestExporterAPI) {
235  EXPECT_THROW(
236  client_->getEkm("EXPORTER-Some-Label", nullptr, 32), std::runtime_error);
237  completeHandshake();
238  client_->getEkm("EXPORTER-Some-Label", nullptr, 32);
239 }
240 
241 TEST_F(AsyncFizzClientTest, TestHandshakeError) {
242  connect();
243  EXPECT_CALL(*machine_, _processSocketData(_, _))
244  .WillOnce(InvokeWithoutArgs([]() {
245  return detail::actions(ReportError("unit test"), WaitForData());
246  }));
247  EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
248  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
249 }
250 
251 TEST_F(AsyncFizzClientTest, TestHandshakeErrorDelete) {
252  connect();
253  EXPECT_CALL(*machine_, _processSocketData(_, _))
254  .WillOnce(InvokeWithoutArgs([]() {
255  return detail::actions(ReportError("unit test"), WaitForData());
256  }));
257  EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_))
258  .WillOnce(InvokeWithoutArgs([this]() { client_.reset(); }));
259  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
260 }
261 
262 TEST_F(AsyncFizzClientTest, TestDeliverAppData) {
263  completeHandshake();
264  client_->setReadCB(&readCallback_);
265  EXPECT_CALL(*machine_, _processSocketData(_, _))
266  .WillOnce(InvokeWithoutArgs([]() {
267  return detail::actions(
269  }));
270  EXPECT_CALL(readCallback_, readBufferAvailable_(_));
271  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
272 }
273 
274 TEST_F(AsyncFizzClientTest, TestWriteToSocket) {
275  completeHandshake();
276  client_->setReadCB(&readCallback_);
277  EXPECT_CALL(*machine_, _processSocketData(_, _))
278  .WillOnce(InvokeWithoutArgs([]() {
279  TLSContent record;
281  record.data = IOBuf::copyBuffer("XYZ");
284  write.contents.emplace_back(std::move(record));
285  return detail::actions(std::move(write), WaitForData());
286  }));
287  EXPECT_CALL(*socket_, writeChain(_, _, _));
288  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
289 }
290 
291 TEST_F(AsyncFizzClientTest, TestMutateState) {
292  completeHandshake();
293  client_->setReadCB(&readCallback_);
294  uint32_t numTimesRun = 0;
295  EXPECT_CALL(*machine_, _processSocketData(_, _))
296  .WillOnce(InvokeWithoutArgs([&numTimesRun]() {
297  return detail::actions(
298  [&numTimesRun](State& newState) {
299  numTimesRun++;
300  newState.state() = StateEnum::Error;
301  },
302  WaitForData());
303  }));
304  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
305  EXPECT_EQ(client_->getState().state(), StateEnum::Error);
306  EXPECT_EQ(numTimesRun, 1);
307 }
308 
309 TEST_F(AsyncFizzClientTest, TestCloseHandshake) {
310  connect();
311  expectAppClose();
312  EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
313  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
314  client_->closeNow();
315 }
316 
317 TEST_F(AsyncFizzClientTest, TestConnecting) {
318  ON_CALL(*socket_, connecting()).WillByDefault(Return(true));
319  EXPECT_TRUE(client_->connecting());
320  ON_CALL(*socket_, connecting()).WillByDefault(Return(false));
321  connect();
322  EXPECT_TRUE(client_->connecting());
323  EXPECT_CALL(*machine_, _processSocketData(_, _))
324  .WillOnce(InvokeWithoutArgs([]() {
326  }));
327  EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
328  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
329  EXPECT_FALSE(client_->connecting());
330 }
331 
332 TEST_F(AsyncFizzClientTest, TestGoodSocket) {
333  connect();
334  ON_CALL(*socket_, good()).WillByDefault(Return(true));
335  EXPECT_TRUE(client_->good());
336  ON_CALL(*socket_, good()).WillByDefault(Return(false));
337  EXPECT_FALSE(client_->good());
338 }
339 
340 TEST_F(AsyncFizzClientTest, TestGoodState) {
341  completeHandshake();
342  ON_CALL(*socket_, good()).WillByDefault(Return(true));
343  EXPECT_TRUE(client_->good());
344  EXPECT_CALL(*machine_, _processSocketData(_, _))
345  .WillOnce(InvokeWithoutArgs([]() {
346  return detail::actions(
347  [](State& newState) { newState.state() = StateEnum::Error; });
348  }));
349  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
350  EXPECT_FALSE(client_->good());
351 }
352 
353 TEST_F(AsyncFizzClientTest, TestSocketConnect) {
355  EventBase evb;
358 
360  auto server = std::make_unique<TestServer>();
361 
362  EXPECT_CALL(*machine_, _processConnect(_, _, _, _, _, _))
363  .WillOnce(InvokeWithoutArgs([]() {
365  }));
366  EXPECT_CALL(cb, _connectSuccess()).WillOnce(Invoke([&evbClient]() {
367  evbClient->closeNow();
368  }));
369 
370  evbClient->connect(
371  server->getAddress(),
372  &cb,
373  nullptr,
374  std::string("www.example.com"),
375  pskIdentity_);
376 
377  evb.loop();
378 }
379 
380 TEST_F(AsyncFizzClientTest, TestSocketConnectWithUnsupportedTransport) {
382  EXPECT_CALL(cb, _connectErr(_))
383  .WillOnce(Invoke([](const AsyncSocketException& ex) {
384  EXPECT_THAT(ex.what(), HasSubstr("could not find underlying socket"));
385  }));
386  EXPECT_CALL(*socket_, getWrappedTransport()).WillOnce(Return(nullptr));
387  client_->connect(
388  SocketAddress(),
389  &cb,
390  nullptr,
391  std::string("www.example.com"),
392  pskIdentity_);
393 }
394 
395 TEST_F(AsyncFizzClientTest, TestHandshakeConnectWithUnopenedSocket) {
396  client_.reset();
397  EventBase evb;
401  EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_))
402  .WillOnce(Invoke([](exception_wrapper ex) {
403  EXPECT_THAT(
404  ex.what().toStdString(),
405  HasSubstr("handshake connect called but socket isn't open"));
406  }));
407  EXPECT_CALL(*machine_, _processConnect(_, _, _, _, _, _)).Times(0);
408  evbClient->connect(
409  &handshakeCallback_,
410  nullptr,
411  std::string("www.example.com"),
412  pskIdentity_);
413  EXPECT_FALSE(evbClient->good());
414 }
415 
416 TEST_F(AsyncFizzClientTest, TestSocketConnectWithOpenSocket) {
418  EXPECT_CALL(cb, _connectErr(_))
419  .WillOnce(Invoke([](const AsyncSocketException& ex) {
420  EXPECT_THAT(ex.what(), HasSubstr("socket already open"));
421  }));
422  EventBase evb;
423  MockAsyncSocket mockSocket(&evb);
424  EXPECT_CALL(*socket_, getWrappedTransport()).WillOnce(Return(&mockSocket));
425  EXPECT_CALL(mockSocket, connect_(_, _, _, _, _))
426  .WillOnce(Invoke([](AsyncSocket::ConnectCallback* cb,
427  const SocketAddress&,
428  int,
429  const AsyncSocket::OptionMap&,
430  const SocketAddress&) {
432  AsyncSocketException::ALREADY_OPEN, "socket already open"));
433  }));
434  EXPECT_CALL(*machine_, _processConnect(_, _, _, _, _, _)).Times(0);
435  client_->connect(
436  SocketAddress(),
437  &cb,
438  nullptr,
439  std::string("www.example.com"),
440  pskIdentity_);
441 }
442 
443 TEST_F(AsyncFizzClientTest, TestApplicationProtocol) {
444  completeHandshake();
445  EXPECT_EQ(client_->getApplicationProtocol(), "h2");
446 }
447 
448 TEST_F(AsyncFizzClientTest, TestApplicationProtocolNone) {
449  connect();
450  EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
451  fullHandshakeSuccess(false, "");
452  EXPECT_EQ(client_->getApplicationProtocol(), "");
453 }
454 
455 TEST_F(AsyncFizzClientTest, TestPskResumed) {
456  connect();
457  EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
458  fullHandshakeSuccess(false, "h2", nullptr, nullptr, true);
459  EXPECT_TRUE(client_->pskResumed());
460 }
461 
462 TEST_F(AsyncFizzClientTest, TestNoPskResumption) {
463  connect();
464  EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
465  fullHandshakeSuccess(false, "h2", nullptr, nullptr, false);
466  EXPECT_FALSE(client_->pskResumed());
467 }
468 
469 TEST_F(AsyncFizzClientTest, TestGetCertsNone) {
470  completeHandshake();
471  EXPECT_EQ(client_->getSelfCert(), nullptr);
472  EXPECT_EQ(client_->getPeerCert(), nullptr);
473 }
474 
475 TEST_F(AsyncFizzClientTest, TestGetCerts) {
476  auto clientCert = std::make_shared<MockCert>();
477  auto serverCert = std::make_shared<MockCert>();
478  connect();
479  EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
480  fullHandshakeSuccess(false, "h2", clientCert, serverCert);
481  EXPECT_CALL(*clientCert, getX509());
482  EXPECT_EQ(client_->getSelfCert(), nullptr);
483  EXPECT_CALL(*serverCert, getX509());
484  EXPECT_EQ(client_->getPeerCert(), nullptr);
485 }
486 
487 TEST_F(AsyncFizzClientTest, TestEarlyHandshake) {
488  completeEarlyHandshake();
489  fullHandshakeSuccess(true);
490  EXPECT_TRUE(client_->isReplaySafe());
491  EXPECT_TRUE(client_->pskResumed());
492 }
493 
494 TEST_F(AsyncFizzClientTest, TestEarlyParams) {
495  auto clientCert = std::make_shared<MockCert>();
496  auto serverCert = std::make_shared<MockCert>();
497  auto params = getEarlyDataParams();
498  params.clientCert = clientCert;
499  params.serverCert = serverCert;
500  completeEarlyHandshake(std::move(params));
501  EXPECT_EQ(client_->getApplicationProtocol(), "h2");
502  EXPECT_CALL(*clientCert, getX509());
503  EXPECT_EQ(client_->getSelfCert(), nullptr);
504  EXPECT_CALL(*serverCert, getX509());
505  EXPECT_EQ(client_->getPeerCert(), nullptr);
506 }
507 
508 TEST_F(AsyncFizzClientTest, TestEarlyApplicationProtocolNone) {
509  auto params = getEarlyDataParams();
510  params.alpn = none;
511  completeEarlyHandshake(std::move(params));
512  EXPECT_EQ(client_->getApplicationProtocol(), "");
513 }
514 
515 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeWrite) {
516  completeEarlyHandshake();
517 
518  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
519  .WillOnce(InvokeWithoutArgs([]() { return detail::actions(); }));
520  client_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
521 
522  fullHandshakeSuccess(true);
523 
524  EXPECT_CALL(*machine_, _processAppWrite(_, _))
525  .WillOnce(InvokeWithoutArgs([]() { return detail::actions(); }));
526  client_->writeChain(nullptr, IOBuf::copyBuffer("HTTP POST"));
527 }
528 
529 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeReplaySafeCallback) {
530  completeEarlyHandshake();
531  client_->setReplaySafetyCallback(&mockReplayCallback_);
532 
533  EXPECT_CALL(*machine_, _processAppWrite(_, _))
534  .WillOnce(InvokeWithoutArgs([]() { return detail::actions(); }));
535  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).WillOnce(Invoke([this]() {
536  client_->writeChain(nullptr, IOBuf::copyBuffer("HTTP POST"));
537  }));
538  fullHandshakeSuccess(true);
539 }
540 
541 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeReplaySafeCallbackRemoved) {
542  completeEarlyHandshake();
543  client_->setReplaySafetyCallback(&mockReplayCallback_);
544  client_->setReplaySafetyCallback(nullptr);
545 
546  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
547  fullHandshakeSuccess(true);
548 }
549 
550 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeOverLimit) {
551  completeEarlyHandshake();
552  client_->setReplaySafetyCallback(&mockReplayCallback_);
553 
554  auto earlyWrite = IOBuf::copyBuffer("earlywrite");
555  auto longWrite = IOBuf::create(2000);
556  std::memset(longWrite->writableData(), 'a', 2000);
557  longWrite->append(2000);
558  auto shortWrite = IOBuf::copyBuffer("shortwrite");
559  auto replaySafeWrite = IOBuf::copyBuffer("replaysafe");
560 
561  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
562  .WillOnce(Invoke([&earlyWrite](const State&, EarlyAppWrite& write) {
563  EXPECT_TRUE(IOBufEqualTo()(write.data, earlyWrite));
564  return detail::actions();
565  }));
566  client_->writeChain(nullptr, earlyWrite->clone());
567  client_->writeChain(nullptr, longWrite->clone());
568  client_->writeChain(nullptr, shortWrite->clone());
569 
570  Sequence s;
571  EXPECT_CALL(*machine_, _processAppWrite(_, _))
572  .InSequence(s)
573  .WillOnce(Invoke([&longWrite](const State&, AppWrite& write) {
574  EXPECT_TRUE(IOBufEqualTo()(write.data, longWrite));
575  return detail::actions();
576  }));
577  EXPECT_CALL(*machine_, _processAppWrite(_, _))
578  .InSequence(s)
579  .WillOnce(Invoke([&shortWrite](const State&, AppWrite& write) {
580  EXPECT_TRUE(IOBufEqualTo()(write.data, shortWrite));
581  return detail::actions();
582  }));
583  EXPECT_CALL(*machine_, _processAppWrite(_, _))
584  .InSequence(s)
585  .WillOnce(Invoke([&replaySafeWrite](const State&, AppWrite& write) {
586  EXPECT_TRUE(IOBufEqualTo()(write.data, replaySafeWrite));
587  return detail::actions();
588  }));
589 
590  EXPECT_CALL(mockReplayCallback_, onReplaySafe_())
591  .WillOnce(Invoke([this, &replaySafeWrite]() {
592  client_->writeChain(nullptr, replaySafeWrite->clone());
593  }));
594  fullHandshakeSuccess(true);
595 }
596 
597 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeAllOverLimit) {
598  completeEarlyHandshake();
599  client_->setReplaySafetyCallback(&mockReplayCallback_);
600 
601  auto buf = IOBuf::create(2000);
602  std::memset(buf->writableData(), 'a', 2000);
603  buf->append(2000);
604  client_->writeChain(nullptr, buf->clone());
605 
606  EXPECT_CALL(*machine_, _processAppWrite(_, _))
607  .WillOnce(Invoke([&buf](const State&, AppWrite& write) {
608  EXPECT_TRUE(IOBufEqualTo()(write.data, buf));
609  return detail::actions();
610  }));
611  EXPECT_CALL(mockReplayCallback_, onReplaySafe_());
612  fullHandshakeSuccess(true);
613 }
614 
615 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeRejectedFatalError) {
616  client_->setEarlyDataRejectionPolicy(
618  completeEarlyHandshake();
619 
620  auto buf = IOBuf::create(2000);
621  std::memset(buf->writableData(), 'a', 2000);
622  buf->append(2000);
623  client_->writeChain(nullptr, std::move(buf));
624  client_->writeChain(&writeCallback_, IOBuf::copyBuffer("write"));
625 
626  EXPECT_CALL(writeCallback_, writeErr_(0, _));
627  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
628  fullHandshakeSuccess(false);
629 }
630 
631 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeRejectedPendingWriteError) {
632  client_->setEarlyDataRejectionPolicy(
634  completeEarlyHandshake();
635  client_->setReplaySafetyCallback(&mockReplayCallback_);
636  client_->setReadCB(&readCallback_);
637  EXPECT_CALL(readCallback_, readErr_(_))
638  .WillOnce(Invoke([](const AsyncSocketException& ex) {
640  }));
641  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
642  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
643  fullHandshakeSuccess(false);
644 }
645 
646 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeRejectedAutoResendNoData) {
647  client_->setEarlyDataRejectionPolicy(
649  completeEarlyHandshake();
650  client_->setReplaySafetyCallback(&mockReplayCallback_);
651  EXPECT_CALL(mockReplayCallback_, onReplaySafe_());
652  fullHandshakeSuccess(false);
653 }
654 
655 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeRejectedAutoResend) {
656  client_->setEarlyDataRejectionPolicy(
658  completeEarlyHandshake();
659 
660  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
661  .WillOnce(Invoke([](const State&, EarlyAppWrite& write) {
662  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("aaaa")));
663  return detail::actions();
664  }));
665  client_->writeChain(nullptr, IOBuf::copyBuffer("aaaa"));
666  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
667  .WillOnce(Invoke([](const State&, EarlyAppWrite& write) {
668  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("bbbb")));
669  return detail::actions();
670  }));
671  client_->writeChain(nullptr, IOBuf::copyBuffer("bbbb"));
672 
673  EXPECT_CALL(*machine_, _processAppWrite(_, _))
674  .WillOnce(Invoke([](const State&, AppWrite& write) {
675  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("aaaabbbb")));
676  return detail::actions();
677  }));
678  fullHandshakeSuccess(false);
679 }
680 
681 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeRejectedAutoResendOrder) {
682  client_->setEarlyDataRejectionPolicy(
684  completeEarlyHandshake();
685  client_->setReplaySafetyCallback(&mockReplayCallback_);
686 
687  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
688  .WillOnce(Invoke([](const State&, EarlyAppWrite& write) {
689  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("aaaa")));
690  return detail::actions();
691  }));
692  client_->writeChain(nullptr, IOBuf::copyBuffer("aaaa"));
693  auto buf = IOBuf::create(2000);
694  std::memset(buf->writableData(), 'b', 2000);
695  buf->append(2000);
696  client_->writeChain(nullptr, buf->clone());
697 
698  Sequence s;
699  EXPECT_CALL(*machine_, _processAppWrite(_, _))
700  .InSequence(s)
701  .WillOnce(Invoke([](const State&, AppWrite& write) {
702  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("aaaa")));
703  return detail::actions();
704  }));
705  EXPECT_CALL(*machine_, _processAppWrite(_, _))
706  .InSequence(s)
707  .WillOnce(Invoke([&buf](const State&, AppWrite& write) {
708  EXPECT_TRUE(IOBufEqualTo()(write.data, buf));
709  return detail::actions();
710  }));
711  EXPECT_CALL(*machine_, _processAppWrite(_, _))
712  .InSequence(s)
713  .WillOnce(Invoke([](const State&, AppWrite& write) {
714  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("cccc")));
715  return detail::actions();
716  }));
717 
718  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).WillOnce(Invoke([this]() {
719  client_->writeChain(nullptr, IOBuf::copyBuffer("cccc"));
720  }));
721  fullHandshakeSuccess(false);
722 }
723 
724 TEST_F(AsyncFizzClientTest, TestEarlyHandshakeRejectedAutoResendDeletedBuffer) {
725  client_->setEarlyDataRejectionPolicy(
727  completeEarlyHandshake();
728 
729  auto buf = IOBuf::copyBuffer("aaaa");
730  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
731  .WillOnce(Invoke([&buf](const State&, EarlyAppWrite& write) {
732  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("aaaa")));
733  buf.reset();
734  return detail::actions();
735  }));
736  client_->write(nullptr, buf->data(), buf->length());
737 
738  EXPECT_CALL(*machine_, _processAppWrite(_, _))
739  .WillOnce(Invoke([](const State&, AppWrite& write) {
740  EXPECT_TRUE(IOBufEqualTo()(write.data, IOBuf::copyBuffer("aaaa")));
741  return detail::actions();
742  }));
743  fullHandshakeSuccess(false);
744 }
745 
746 TEST_F(AsyncFizzClientTest, TestEarlyRejectResendDifferentAlpn) {
747  client_->setEarlyDataRejectionPolicy(
749  completeEarlyHandshake();
750  client_->setReplaySafetyCallback(&mockReplayCallback_);
751  client_->setReadCB(&readCallback_);
752  EXPECT_CALL(readCallback_, readErr_(_))
753  .WillOnce(Invoke([](const AsyncSocketException& ex) {
755  }));
756  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
757  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
758  fullHandshakeSuccess(false, "h3");
759 }
760 
761 TEST_F(AsyncFizzClientTest, TestEarlyRejectResendDifferentNoAlpn) {
762  client_->setEarlyDataRejectionPolicy(
764  completeEarlyHandshake();
765  client_->setReplaySafetyCallback(&mockReplayCallback_);
766  client_->setReadCB(&readCallback_);
767  EXPECT_CALL(readCallback_, readErr_(_))
768  .WillOnce(Invoke([](const AsyncSocketException& ex) {
770  }));
771  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
772  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
773  fullHandshakeSuccess(false, "h3");
774 }
775 
776 TEST_F(AsyncFizzClientTest, TestEarlyRejectResendDifferentVersion) {
777  client_->setEarlyDataRejectionPolicy(
779  auto params = getEarlyDataParams();
781  completeEarlyHandshake(std::move(params));
782  client_->setReplaySafetyCallback(&mockReplayCallback_);
783  client_->setReadCB(&readCallback_);
784  EXPECT_CALL(readCallback_, readErr_(_))
785  .WillOnce(Invoke([](const AsyncSocketException& ex) {
787  }));
788  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
789  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
790  fullHandshakeSuccess(false);
791 }
792 
793 TEST_F(AsyncFizzClientTest, TestEarlyRejectResendDifferentCipher) {
794  client_->setEarlyDataRejectionPolicy(
796  auto params = getEarlyDataParams();
798  completeEarlyHandshake(std::move(params));
799  client_->setReplaySafetyCallback(&mockReplayCallback_);
800  client_->setReadCB(&readCallback_);
801  EXPECT_CALL(readCallback_, readErr_(_))
802  .WillOnce(Invoke([](const AsyncSocketException& ex) {
804  }));
805  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
806  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
807  fullHandshakeSuccess(false);
808 }
809 
810 TEST_F(AsyncFizzClientTest, TestEarlyRejectNoClientCert) {
811  client_->setEarlyDataRejectionPolicy(
813  auto params = getEarlyDataParams();
814  params.clientCert = std::make_shared<MockCert>();
815  completeEarlyHandshake(std::move(params));
816  client_->setReplaySafetyCallback(&mockReplayCallback_);
817  client_->setReadCB(&readCallback_);
818  EXPECT_CALL(readCallback_, readErr_(_))
819  .WillOnce(Invoke([](const AsyncSocketException& ex) {
821  }));
822  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
823  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
824  fullHandshakeSuccess(false);
825 }
826 
827 TEST_F(AsyncFizzClientTest, TestEarlyRejectNoServerCert) {
828  client_->setEarlyDataRejectionPolicy(
830  auto params = getEarlyDataParams();
831  params.clientCert = std::make_shared<MockCert>();
832  completeEarlyHandshake(std::move(params));
833  client_->setReplaySafetyCallback(&mockReplayCallback_);
834  client_->setReadCB(&readCallback_);
835  EXPECT_CALL(readCallback_, readErr_(_))
836  .WillOnce(Invoke([](const AsyncSocketException& ex) {
838  }));
839  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
840  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
841  fullHandshakeSuccess(false);
842 }
843 
844 TEST_F(AsyncFizzClientTest, TestEarlyRejectDifferentServerIdentity) {
845  client_->setEarlyDataRejectionPolicy(
847  auto cert1 = std::make_shared<MockCert>();
848  auto cert2 = std::make_shared<MockCert>();
849  auto params = getEarlyDataParams();
850  params.serverCert = cert1;
851  completeEarlyHandshake(std::move(params));
852  client_->setReplaySafetyCallback(&mockReplayCallback_);
853  client_->setReadCB(&readCallback_);
854  EXPECT_CALL(readCallback_, readErr_(_))
855  .WillOnce(Invoke([](const AsyncSocketException& ex) {
857  }));
858  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
859  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
860  EXPECT_CALL(*cert1, getIdentity()).WillOnce(Return("id1"));
861  EXPECT_CALL(*cert2, getIdentity()).WillOnce(Return("id2"));
862  fullHandshakeSuccess(false, "h2", nullptr, cert2);
863 }
864 
865 TEST_F(AsyncFizzClientTest, TestEarlyRejectSameServerIdentity) {
866  client_->setEarlyDataRejectionPolicy(
868  auto cert1 = std::make_shared<MockCert>();
869  auto cert2 = std::make_shared<MockCert>();
870  auto params = getEarlyDataParams();
871  params.serverCert = cert1;
872  completeEarlyHandshake(std::move(params));
873  client_->setReplaySafetyCallback(&mockReplayCallback_);
874  EXPECT_CALL(mockReplayCallback_, onReplaySafe_());
875  EXPECT_CALL(*cert1, getIdentity()).WillOnce(Return("id"));
876  EXPECT_CALL(*cert2, getIdentity()).WillOnce(Return("id"));
877  fullHandshakeSuccess(false, "h2", nullptr, cert2);
878 }
879 
880 TEST_F(AsyncFizzClientTest, TestEarlyRejectDifferentClientIdentity) {
881  client_->setEarlyDataRejectionPolicy(
883  auto cert1 = std::make_shared<MockCert>();
884  auto cert2 = std::make_shared<MockCert>();
885  auto params = getEarlyDataParams();
886  params.clientCert = cert1;
887  completeEarlyHandshake(std::move(params));
888  client_->setReplaySafetyCallback(&mockReplayCallback_);
889  client_->setReadCB(&readCallback_);
890  EXPECT_CALL(readCallback_, readErr_(_))
891  .WillOnce(Invoke([](const AsyncSocketException& ex) {
893  }));
894  EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
895  EXPECT_CALL(mockReplayCallback_, onReplaySafe_()).Times(0);
896  EXPECT_CALL(*cert1, getIdentity()).WillOnce(Return("id1"));
897  EXPECT_CALL(*cert2, getIdentity()).WillOnce(Return("id2"));
898  fullHandshakeSuccess(false, "h2", cert2, nullptr);
899 }
900 
901 TEST_F(AsyncFizzClientTest, TestEarlyRejectSameClientIdentity) {
902  client_->setEarlyDataRejectionPolicy(
904  auto cert1 = std::make_shared<MockCert>();
905  auto cert2 = std::make_shared<MockCert>();
906  auto params = getEarlyDataParams();
907  params.clientCert = cert1;
908  completeEarlyHandshake(std::move(params));
909  client_->setReplaySafetyCallback(&mockReplayCallback_);
910  EXPECT_CALL(mockReplayCallback_, onReplaySafe_());
911  EXPECT_CALL(*cert1, getIdentity()).WillOnce(Return("id"));
912  EXPECT_CALL(*cert2, getIdentity()).WillOnce(Return("id"));
913  fullHandshakeSuccess(false, "h2", cert2, nullptr);
914 }
915 
916 TEST_F(AsyncFizzClientTest, TestEarlyRejectRemovePsk) {
917  EXPECT_CALL(*mockPskCache_, removePsk(*pskIdentity_));
918  completeEarlyHandshake();
919  fullHandshakeSuccess(false);
920 }
921 
922 TEST_F(AsyncFizzClientTest, TestEarlyWriteRejected) {
923  completeEarlyHandshake();
924  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
925  .WillOnce(Invoke([](const State&, EarlyAppWrite& write) {
927  failed.write = std::move(write);
928  return detail::actions(std::move(failed));
929  }));
930  EXPECT_CALL(writeCallback_, writeSuccess_());
931  client_->writeChain(&writeCallback_, IOBuf::copyBuffer("HTTP GET"));
932 }
933 
934 TEST_F(AsyncFizzClientTest, TestEarlyWriteRejectedNullCallback) {
935  completeEarlyHandshake();
936  EXPECT_CALL(*machine_, _processEarlyAppWrite(_, _))
937  .WillOnce(Invoke([](const State&, EarlyAppWrite& write) {
939  failed.write = std::move(write);
940  return detail::actions(std::move(failed));
941  }));
942  client_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
943 }
944 
945 TEST_F(AsyncFizzClientTest, TestErrorStopsActions) {
946  completeHandshake();
947  client_->setReadCB(&readCallback_);
948  EXPECT_CALL(*machine_, _processSocketData(_, _))
949  .WillOnce(InvokeWithoutArgs(
950  []() { return detail::actions(ReportError("unit test")); }));
951  EXPECT_FALSE(client_->error());
952  socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
953  EXPECT_TRUE(client_->error());
954 }
955 
956 TEST_F(AsyncFizzClientTest, TestNewCachedPskActions) {
957  completeHandshake();
958  client_->setReadCB(&readCallback_);
959  EXPECT_CALL(*machine_, _processSocketData(_, _))
960  .WillOnce(InvokeWithoutArgs(
961  []() { return detail::actions(NewCachedPsk(), WaitForData()); }));
962  EXPECT_CALL(*mockPskCache_, putPsk(*pskIdentity_, _));
963  socketReadCallback_->readBufferAvailable(
964  IOBuf::copyBuffer("NewSessionTicket"));
965 }
966 
967 TEST_F(AsyncFizzClientTest, TestNewCachedPskActionsWithEmptyPskIdentity) {
968  pskIdentity_ = folly::none;
969  completeHandshake();
970  client_->setReadCB(&readCallback_);
971  EXPECT_CALL(*machine_, _processSocketData(_, _))
972  .WillOnce(InvokeWithoutArgs(
973  []() { return detail::actions(NewCachedPsk(), WaitForData()); }));
974  EXPECT_CALL(*mockPskCache_, putPsk(_, _)).Times(0);
975  socketReadCallback_->readBufferAvailable(
976  IOBuf::copyBuffer("NewSessionTicket"));
977 }
978 
979 } // namespace test
980 } // namespace client
981 } // namespace fizz
folly::fbstring what() const
std::unique_ptr< folly::IOBuf > data
Definition: Params.h:48
static Optional< EarlyDataParams > getEarlyDataParams(const FizzClientContext &context, const Optional< CachedPsk > &psk)
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
int connect(NetworkSocket s, const sockaddr *name, socklen_t namelen)
Definition: NetOps.cpp:94
GTEST_API_ Cardinality AtLeast(int n)
void completeEarlyHandshake(EarlyDataParams params=getEarlyDataParams())
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
void fullHandshakeSuccess(bool acceptEarlyData, std::string alpn="h2", std::shared_ptr< const Cert > clientCert=nullptr, std::shared_ptr< const Cert > serverCert=nullptr, bool pskResumed=false)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::small_vector< TLSContent, 4 > contents
Definition: Actions.h:41
virtual void connectErr(const AsyncSocketException &ex) noexcept=0
StringPiece alpn
static bool failed
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
std::unique_ptr< AsyncFizzClientT, folly::DelayedDestruction::Destructor > UniquePtr
MockHandshakeCallbackT< MockClientStateMachineInstance > handshakeCallback_
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Definition: error.h:48
PolymorphicAction< internal::InvokeWithoutArgsAction< FunctionImpl > > InvokeWithoutArgs(FunctionImpl function_impl)
constexpr bool empty() const
Definition: Range.h:443
std::map< OptionKey, int > OptionMap
Definition: AsyncSocket.h:376
TEST_F(AsyncFizzClientTest, TestConnect)
constexpr Params params[]
std::unique_ptr< AsyncTransportWrapper, Destructor > UniquePtr
AsyncTransportWrapper::ReadCallback * socketReadCallback_
PolymorphicMatcher< internal::HasSubstrMatcher< internal::string > > HasSubstr(const internal::string &substring)
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
std::vector< Action > Actions
Definition: Actions.h:81
MATCHER_P(BufMatches, expected,"")
AsyncServerSocket::UniquePtr socket_
std::basic_string< E, T, A > toStdString() const
Definition: FBString.h:1227
EncryptionLevel encryptionLevel
Definition: RecordLayer.h:21
Definition: Actions.h:16
std::shared_ptr< const Cert > serverCert
MockClientStateMachineInstance * machine_
Actions actions(Args &&...act)
Definition: Actions.h:86
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_THAT(value, matcher)
StateEnum state() const
#define ON_CALL(obj, call)
StringPiece sni
#define MOCK_METHOD1(m,...)
const char * string
Definition: Conv.cpp:212
ContentType contentType
Definition: RecordLayer.h:20
static set< string > s
std::shared_ptr< MockPskCache > mockPskCache_
std::shared_ptr< const Cert > clientCert
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
folly::Optional< std::string > alpn
Definition: State.h:54
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
AsyncFizzClientT< MockClientStateMachineInstance >::UniquePtr client_
static MockClientStateMachineInstance * instance
AsyncSocketExceptionType getType() const noexcept
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
void connectErr(const AsyncSocketException &ex) noexceptoverride
ProtocolVersion version
Definition: State.h:50
std::unique_ptr< folly::IOBuf > data
Definition: Params.h:54
std::shared_ptr< FizzClientContext > context_
constexpr None none
Definition: Optional.h:87
internal::ReturnAction< R > Return(R value)
#define MOCK_METHOD0(m,...)