proxygen
FizzBaseTest.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 
12 #include <fizz/protocol/FizzBase.h>
13 #include <folly/futures/Future.h>
16 
17 namespace fizz {
18 namespace test {
19 
20 using namespace folly;
21 using namespace folly::test;
22 using namespace testing;
23 
26  write.appToken = IOBuf::copyBuffer(str);
27  return write;
28 }
29 
30 static AppWrite appWrite(const std::string& str) {
32  write.data = IOBuf::copyBuffer(str);
33  return write;
34 }
35 
36 MATCHER_P(WriteNewSessionTicketMatches, expected, "") {
37  return IOBufEqualTo()(IOBuf::copyBuffer(expected), arg.appToken);
38 }
39 
40 MATCHER_P(WriteMatches, expected, "") {
41  return IOBufEqualTo()(IOBuf::copyBuffer(expected), arg.data);
42 }
43 
44 enum class StateEnum { NotError, Error };
45 
46 struct State {
47  StateEnum state() const {
48  return state_;
49  }
50 
52 };
53 
54 struct A1 {};
55 struct A2 {};
56 using Action = boost::variant<A1, A2>;
57 using Actions = std::vector<Action>;
58 
60  public:
61  using StateType = State;
64 
66  instance = this;
67  }
68 
69  MOCK_METHOD2(processSocketData, Future<Actions>(const State&, IOBufQueue&));
70 
72  return processAppWrite_(state, write);
73  }
74 
76  const State& state,
77  EarlyAppWrite&& write) {
78  return processEarlyAppWrite_(state, write);
79  }
80 
82  processWriteNewSessionTicket_,
85  const State& state,
87  return processWriteNewSessionTicket_(state, ticket);
88  }
89  MOCK_METHOD2(processAppWrite_, Future<Actions>(const State&, AppWrite&));
91  processEarlyAppWrite_,
93  MOCK_METHOD1(processAppClose, Future<Actions>(const State&));
94 
96 };
98 
99 class ActionMoveVisitor : public boost::static_visitor<> {
100  public:
101  MOCK_METHOD0(a1, void());
102  MOCK_METHOD0(a2, void());
103 
104  void operator()(A1&) {
105  a1();
106  }
107  void operator()(A2&) {
108  a2();
109  }
110 };
111 
113  : public FizzBase<TestFizzBase, ActionMoveVisitor, TestStateMachine>,
114  public DelayedDestruction {
115  public:
118  state_,
119  queue_,
120  visitor_,
121  this) {}
122 
126 
128  std::move(actions).then(
130  static_cast<
132  this));
133  }
134 };
135 
136 class FizzBaseTest : public Test {
137  public:
138  void SetUp() override {
139  testFizz_.reset(new TestFizzBase());
140  }
141 
142  protected:
143  std::unique_ptr<TestFizzBase, DelayedDestruction::Destructor> testFizz_;
147 };
148 
149 TEST_F(FizzBaseTest, TestReadSingle) {
150  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
151  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
152  EXPECT_CALL(testFizz_->visitor_, a1()).WillOnce(Invoke([this]() {
153  testFizz_->waitForData();
154  }));
155  testFizz_->newTransportData();
156 }
157 
158 TEST_F(FizzBaseTest, TestReadMulti) {
159  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
160  .InSequence(s_)
161  .WillOnce(InvokeWithoutArgs([]() {
162  return Actions{A1(), A2(), A1()};
163  }));
164  EXPECT_CALL(testFizz_->visitor_, a1()).InSequence(s_);
165  EXPECT_CALL(testFizz_->visitor_, a2()).InSequence(s_);
166  EXPECT_CALL(testFizz_->visitor_, a1()).InSequence(s_);
167  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
168  .InSequence(s_)
169  .WillOnce(InvokeWithoutArgs([]() { return Actions{A2()}; }));
170  EXPECT_CALL(testFizz_->visitor_, a2()).InSequence(s_);
171  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
172  .InSequence(s_)
173  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
174  EXPECT_CALL(testFizz_->visitor_, a1())
175  .InSequence(s_)
176  .WillOnce(Invoke([this]() { testFizz_->waitForData(); }));
177  testFizz_->newTransportData();
178 }
179 
180 TEST_F(FizzBaseTest, TestReadNoActions) {
181  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
182  .InSequence(s_)
183  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
184  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
185  .InSequence(s_)
186  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
187  EXPECT_CALL(testFizz_->visitor_, a1())
188  .InSequence(s_)
189  .WillOnce(Invoke([this]() { testFizz_->waitForData(); }));
190  testFizz_->newTransportData();
191 }
192 
193 TEST_F(FizzBaseTest, TestWriteNewSessionTicket) {
194  EXPECT_CALL(*TestStateMachine::instance, processWriteNewSessionTicket_(_, _))
195  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
196  EXPECT_CALL(testFizz_->visitor_, a1());
197  testFizz_->writeNewSessionTicket(WriteNewSessionTicket());
198 }
199 
200 TEST_F(FizzBaseTest, TestWrite) {
201  EXPECT_CALL(*TestStateMachine::instance, processAppWrite_(_, _))
202  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
203  EXPECT_CALL(testFizz_->visitor_, a1());
204  testFizz_->appWrite(AppWrite());
205 }
206 
207 TEST_F(FizzBaseTest, TestEarlyWrite) {
208  EXPECT_CALL(*TestStateMachine::instance, processEarlyAppWrite_(_, _))
209  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
210  EXPECT_CALL(testFizz_->visitor_, a1());
211  testFizz_->earlyAppWrite(EarlyAppWrite());
212 }
213 
214 TEST_F(FizzBaseTest, TestWriteMulti) {
215  EXPECT_CALL(
216  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write1")))
217  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
218  EXPECT_CALL(testFizz_->visitor_, a1());
219  testFizz_->appWrite(appWrite("write1"));
220  EXPECT_CALL(
221  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write2")))
222  .WillOnce(InvokeWithoutArgs([]() { return Actions{A2()}; }));
223  EXPECT_CALL(testFizz_->visitor_, a2());
224  testFizz_->appWrite(appWrite("write2"));
225 }
226 
227 TEST_F(FizzBaseTest, TestAppClose) {
228  EXPECT_CALL(*TestStateMachine::instance, processAppClose(_))
229  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
230  EXPECT_CALL(testFizz_->visitor_, a1());
231  testFizz_->appClose();
232 }
233 
234 TEST_F(FizzBaseTest, TestWriteNewSessionTicketInCallback) {
235  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
236  .InSequence(s_)
237  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
238  EXPECT_CALL(testFizz_->visitor_, a1())
239  .InSequence(s_)
240  .WillOnce(Invoke([this]() {
241  testFizz_->waitForData();
242  testFizz_->writeNewSessionTicket(writeNewSessionTicket("appToken"));
243  }));
244  EXPECT_CALL(
245  *TestStateMachine::instance,
246  processWriteNewSessionTicket_(
247  _, WriteNewSessionTicketMatches("appToken")))
248  .InSequence(s_)
249  .WillOnce(InvokeWithoutArgs([]() { return Actions{A2()}; }));
250  EXPECT_CALL(testFizz_->visitor_, a2())
251  .InSequence(s_)
252  .WillOnce(Invoke([this]() { testFizz_->appWrite(appWrite("write")); }));
253  EXPECT_CALL(
254  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write")))
255  .InSequence(s_)
256  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
257  testFizz_->newTransportData();
258 }
259 
260 TEST_F(FizzBaseTest, TestWriteInCallback) {
261  EXPECT_CALL(
262  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write1")))
263  .InSequence(s_)
264  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
265  EXPECT_CALL(testFizz_->visitor_, a1())
266  .InSequence(s_)
267  .WillOnce(Invoke([this]() {
268  testFizz_->appWrite(appWrite("write2"));
269  testFizz_->appWrite(appWrite("write3"));
270  }));
271  EXPECT_CALL(
272  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write2")))
273  .InSequence(s_)
274  .WillOnce(InvokeWithoutArgs([]() { return Actions{A2()}; }));
275  EXPECT_CALL(testFizz_->visitor_, a2())
276  .InSequence(s_)
277  .WillOnce(Invoke([this]() { testFizz_->appWrite(appWrite("write4")); }));
278  EXPECT_CALL(
279  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write3")))
280  .InSequence(s_)
281  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
282  EXPECT_CALL(
283  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write4")))
284  .InSequence(s_)
285  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
286  testFizz_->appWrite(appWrite("write1"));
287 }
288 
289 TEST_F(FizzBaseTest, TestAppCloseInCallback) {
290  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
291  .InSequence(s_)
292  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
293  EXPECT_CALL(testFizz_->visitor_, a1())
294  .InSequence(s_)
295  .WillOnce(Invoke([this]() { testFizz_->appClose(); }));
296  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
297  .InSequence(s_)
298  .WillOnce(InvokeWithoutArgs([]() { return Actions{A2()}; }));
299  EXPECT_CALL(testFizz_->visitor_, a2())
300  .InSequence(s_)
301  .WillOnce(Invoke([this]() { testFizz_->waitForData(); }));
302  EXPECT_CALL(*TestStateMachine::instance, processAppClose(_))
303  .InSequence(s_)
304  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
305  testFizz_->newTransportData();
306 }
307 
308 TEST_F(FizzBaseTest, TestWriteThenCloseInCallback) {
309  EXPECT_CALL(
310  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write1")))
311  .InSequence(s_)
312  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
313  EXPECT_CALL(testFizz_->visitor_, a1())
314  .InSequence(s_)
315  .WillOnce(Invoke([this]() {
316  testFizz_->appWrite(appWrite("write2"));
317  testFizz_->appClose();
318  }));
319  EXPECT_CALL(
320  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write2")))
321  .InSequence(s_)
322  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
323  EXPECT_CALL(*TestStateMachine::instance, processAppClose(_))
324  .InSequence(s_)
325  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
326  testFizz_->appWrite(appWrite("write1"));
327 }
328 
329 TEST_F(FizzBaseTest, TestDeleteInCallback) {
330  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
331  .InSequence(s_)
332  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
333  EXPECT_CALL(testFizz_->visitor_, a1())
334  .InSequence(s_)
335  .WillOnce(Invoke([this]() { testFizz_.reset(); }));
336  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
337  .InSequence(s_)
338  .WillOnce(InvokeWithoutArgs([]() { return Actions{A2()}; }));
339  EXPECT_CALL(testFizz_->visitor_, a2())
340  .InSequence(s_)
341  .WillOnce(Invoke([ptr = testFizz_.get()]() { ptr->waitForData(); }));
342  testFizz_->newTransportData();
343 }
344 
345 TEST_F(FizzBaseTest, TestStopOnError) {
346  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
347  .InSequence(s_)
348  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
349  EXPECT_CALL(testFizz_->visitor_, a1())
350  .InSequence(s_)
351  .WillOnce(
352  Invoke([this]() { testFizz_->state_.state_ = StateEnum::Error; }));
353  EXPECT_FALSE(testFizz_->inErrorState());
354  testFizz_->newTransportData();
355  EXPECT_TRUE(testFizz_->inErrorState());
356 }
357 
358 TEST_F(FizzBaseTest, TestAsyncAction) {
360  EXPECT_CALL(
361  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write1")))
362  .WillOnce(InvokeWithoutArgs([&p]() { return p.getFuture(); }));
363  testFizz_->appWrite(appWrite("write1"));
364  testFizz_->appWrite(appWrite("write2"));
365  EXPECT_CALL(
366  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write2")))
367  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
368  p.setValue(Actions{});
369 }
370 
371 TEST_F(FizzBaseTest, TestAsyncActionDelete) {
373  EXPECT_CALL(
374  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write1")))
375  .WillOnce(InvokeWithoutArgs([&p]() { return p.getFuture(); }));
376  testFizz_->appWrite(appWrite("write1"));
377  testFizz_->appWrite(appWrite("write2"));
378  testFizz_.reset();
379  EXPECT_CALL(
380  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write2")))
381  .WillOnce(InvokeWithoutArgs([]() { return Actions{}; }));
382  p.setValue(Actions{});
383 }
384 
385 TEST_F(FizzBaseTest, TestActionProcessing) {
386  EXPECT_CALL(*TestStateMachine::instance, processAppClose(_))
387  .WillOnce(InvokeWithoutArgs([this]() {
388  EXPECT_TRUE(testFizz_->actionProcessing());
389  return Actions{};
390  }));
391  EXPECT_FALSE(testFizz_->actionProcessing());
392  testFizz_->appClose();
393  EXPECT_FALSE(testFizz_->actionProcessing());
394 }
395 
396 TEST_F(FizzBaseTest, TestActionProcessingAsync) {
398  EXPECT_CALL(*TestStateMachine::instance, processAppClose(_))
399  .WillOnce(InvokeWithoutArgs([this, &p]() {
400  EXPECT_TRUE(testFizz_->actionProcessing());
401  return p.getFuture();
402  }));
403  EXPECT_FALSE(testFizz_->actionProcessing());
404  testFizz_->appClose();
405  EXPECT_TRUE(testFizz_->actionProcessing());
406  p.setValue(Actions{});
407  EXPECT_FALSE(testFizz_->actionProcessing());
408 }
409 
410 TEST_F(FizzBaseTest, TestErrorPendingEvents) {
411  EXPECT_CALL(
412  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write1")))
413  .WillOnce(InvokeWithoutArgs([]() { return Actions{A1()}; }));
414  EXPECT_CALL(testFizz_->visitor_, a1()).WillOnce(Invoke([this]() {
415  testFizz_->appWrite(appWrite("write2"));
416  EarlyAppWrite earlyWrite;
417  earlyWrite.callback = &earlyWriteCallback_;
418  testFizz_->earlyAppWrite(std::move(earlyWrite));
419  auto w3 = appWrite("write3");
420  w3.callback = &writeCallback_;
421  testFizz_->appWrite(std::move(w3));
422  testFizz_->appWrite(appWrite("write4"));
423  testFizz_->appClose();
424  }));
425  EXPECT_CALL(
426  *TestStateMachine::instance, processAppWrite_(_, WriteMatches("write2")))
427  .WillOnce(InvokeWithoutArgs([this]() {
428  testFizz_->moveToErrorState(
430  return Actions{};
431  }));
432  EXPECT_CALL(earlyWriteCallback_, writeErr_(0, _));
433  EXPECT_CALL(writeCallback_, writeErr_(0, _));
434  EXPECT_FALSE(testFizz_->inErrorState());
435  testFizz_->appWrite(appWrite("write1"));
436  EXPECT_TRUE(testFizz_->inErrorState());
437 }
438 
439 TEST_F(FizzBaseTest, EventAfterErrorState) {
440  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
441  .WillOnce(InvokeWithoutArgs([this]() {
442  testFizz_->moveToErrorState(
444  return Actions{};
445  }));
446  EXPECT_FALSE(testFizz_->inErrorState());
447  testFizz_->newTransportData();
448  EXPECT_TRUE(testFizz_->inErrorState());
449 }
450 
451 TEST_F(FizzBaseTest, TestManyActions) {
452  size_t i = 0;
453  EXPECT_CALL(*TestStateMachine::instance, processSocketData(_, _))
454  .WillRepeatedly(InvokeWithoutArgs([this, &i]() {
455  if (++i == 10000) {
456  testFizz_->waitForData();
457  }
458  return Actions{};
459  }));
460  testFizz_->newTransportData();
461 }
462 } // namespace test
463 } // namespace fizz
Future< Actions > processAppWrite(const State &state, AppWrite &&write)
void * ptr
static WriteNewSessionTicket writeNewSessionTicket(const std::string &str)
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
MATCHER_P(WriteNewSessionTicketMatches, expected,"")
std::string s_
void startActions(Future< Actions > actions)
static TestStateMachine * instance
void processActions(typename TestStateMachine::CompletedActions actions)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
boost::variant< A1, A2 > Action
Future< Actions > processEarlyAppWrite(const State &state, EarlyAppWrite &&write)
static AppWrite appWrite(const std::string &str)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
MockWriteCallback writeCallback_
PolymorphicAction< internal::InvokeWithoutArgsAction< FunctionImpl > > InvokeWithoutArgs(FunctionImpl function_impl)
Future< Actions > processWriteNewSessionTicket(const State &state, WriteNewSessionTicket ticket)
static constexpr StringPiece ticket
State
See Core for details.
Definition: Core.h:43
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
Future< T > getFuture()
Definition: Promise-inl.h:97
Definition: Actions.h:16
ActionMoveVisitor visitor_
Actions actions(Args &&...act)
Definition: Actions.h:86
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
StateEnum state() const
std::vector< Action > Actions
std::unique_ptr< TestFizzBase, DelayedDestruction::Destructor > testFizz_
TEST_F(RSAPSSTest, TestSignVerify)
#define MOCK_METHOD1(m,...)
const char * string
Definition: Conv.cpp:212
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
MockWriteCallback earlyWriteCallback_
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
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
#define MOCK_METHOD2(m,...)
std::unique_ptr< folly::IOBuf > data
Definition: Params.h:54
folly::AsyncTransportWrapper::WriteCallback * callback
Definition: Params.h:47
state
Definition: http_parser.c:272
#define MOCK_METHOD0(m,...)