proxygen
RecordTest.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 #include <fizz/record/test/Mocks.h>
14 
15 #include <folly/String.h>
16 
17 using namespace folly;
18 using namespace folly::io;
19 
20 using testing::_;
21 using namespace testing;
22 
23 namespace fizz {
24 namespace test {
25 
27  public:
29 };
30 
32  public:
34  TLSContent write(TLSMessage&& msg) const override {
35  return _write(msg);
36  }
37 };
38 
39 class RecordTest : public testing::Test {
40  protected:
43 
45 
47 
48  static Buf getBuf(const std::string& hex) {
49  auto data = unhexlify(hex);
50  return IOBuf::copyBuffer(data.data(), data.size());
51  }
52 
53  static void expectSame(const Buf& buf, const std::string& hex) {
54  auto str = buf->moveToFbString().toStdString();
55  EXPECT_EQ(hexlify(str), hex);
56  }
57 };
58 
59 TEST_F(RecordTest, TestNoData) {
60  EXPECT_CALL(read_, read(_)).WillOnce(InvokeWithoutArgs([]() {
61  return none;
62  }));
63  EXPECT_FALSE(read_.readEvent(queue_).hasValue());
64 }
65 
66 TEST_F(RecordTest, TestReadAppData) {
67  EXPECT_CALL(read_, read(_)).WillOnce(InvokeWithoutArgs([]() {
68  return TLSMessage{ContentType::application_data, IOBuf::copyBuffer("hi")};
69  }));
70  auto param = read_.readEvent(queue_);
71  auto& appData = boost::get<AppData>(*param);
72  EXPECT_TRUE(eq_(appData.data, IOBuf::copyBuffer("hi")));
73 }
74 
75 TEST_F(RecordTest, TestAlert) {
76  EXPECT_CALL(read_, read(_)).WillOnce(InvokeWithoutArgs([]() {
77  return TLSMessage{ContentType::alert, getBuf("0202")};
78  }));
79  auto param = read_.readEvent(queue_);
80  boost::get<Alert>(*param);
81 }
82 
83 TEST_F(RecordTest, TestHandshake) {
84  EXPECT_CALL(read_, read(_)).WillOnce(InvokeWithoutArgs([]() {
85  return TLSMessage{ContentType::handshake, getBuf("140000023232")};
86  }));
87  auto param = read_.readEvent(queue_);
88  auto& finished = boost::get<Finished>(*param);
89  expectSame(finished.verify_data, "3232");
90  expectSame(*finished.originalEncoding, "140000023232");
91 }
92 
93 TEST_F(RecordTest, TestHandshakeTooLong) {
94  EXPECT_CALL(read_, read(_)).WillOnce(InvokeWithoutArgs([]() {
95  return TLSMessage{ContentType::handshake, getBuf("14400000")};
96  }));
97  EXPECT_ANY_THROW(read_.readEvent(queue_));
98 }
99 
100 TEST_F(RecordTest, TestHandshakeFragmentedImmediate) {
101  EXPECT_CALL(read_, read(_))
102  .WillOnce(InvokeWithoutArgs([]() {
103  return TLSMessage{ContentType::handshake, getBuf("14000008aabbccdd")};
104  }))
105  .WillOnce(InvokeWithoutArgs([]() {
106  return TLSMessage{ContentType::handshake, getBuf("11223344")};
107  }));
108  auto param = read_.readEvent(queue_);
109  EXPECT_FALSE(read_.hasUnparsedHandshakeData());
110  auto& finished = boost::get<Finished>(*param);
111  expectSame(finished.verify_data, "aabbccdd11223344");
112 }
113 
114 TEST_F(RecordTest, TestHandshakeFragmentedDelayed) {
115  EXPECT_CALL(read_, read(_))
116  .WillOnce(InvokeWithoutArgs([]() {
117  return TLSMessage{ContentType::handshake, getBuf("14000008aabbccdd")};
118  }))
119  .WillOnce(InvokeWithoutArgs([]() { return folly::none; }));
120  EXPECT_FALSE(read_.readEvent(queue_).hasValue());
121  EXPECT_TRUE(read_.hasUnparsedHandshakeData());
122  EXPECT_CALL(read_, read(_)).WillOnce(InvokeWithoutArgs([]() {
123  return TLSMessage{ContentType::handshake, getBuf("11223344")};
124  }));
125  auto param = read_.readEvent(queue_);
126  auto& finished = boost::get<Finished>(*param);
127  expectSame(finished.verify_data, "aabbccdd11223344");
128 }
129 
130 TEST_F(RecordTest, TestHandshakeCoalesced) {
131  EXPECT_CALL(read_, read(_)).WillOnce(InvokeWithoutArgs([]() {
132  return TLSMessage{ContentType::handshake,
133  getBuf("14000002aabb14000002ccdd")};
134  }));
135  auto param = read_.readEvent(queue_);
136  auto& finished = boost::get<Finished>(*param);
137  expectSame(finished.verify_data, "aabb");
138  EXPECT_TRUE(read_.hasUnparsedHandshakeData());
139  param = read_.readEvent(queue_);
140  auto& finished2 = boost::get<Finished>(*param);
141  expectSame(finished2.verify_data, "ccdd");
142  EXPECT_FALSE(read_.hasUnparsedHandshakeData());
143 }
144 
145 TEST_F(RecordTest, TestHandshakeSpliced) {
146  EXPECT_CALL(read_, read(_))
147  .WillOnce(InvokeWithoutArgs([]() {
148  return TLSMessage{ContentType::handshake, getBuf("01000010abcd")};
149  }))
150  .WillOnce(InvokeWithoutArgs([]() {
151  return TLSMessage{ContentType::application_data,
152  IOBuf::copyBuffer("hi")};
153  }));
154  EXPECT_ANY_THROW(read_.readEvent(queue_));
155 }
156 
157 TEST_F(RecordTest, TestWriteAppData) {
158  EXPECT_CALL(write_, _write(_)).WillOnce(Invoke([&](TLSMessage& msg) {
159  TLSContent content;
160  content.contentType = msg.type;
161  content.encryptionLevel = write_.getEncryptionLevel();
162  content.data = nullptr;
163  EXPECT_EQ(msg.type, ContentType::application_data);
164  return content;
165  }));
166  write_.writeAppData(IOBuf::copyBuffer("hi"));
167 }
168 
169 TEST_F(RecordTest, TestWriteAlert) {
170  EXPECT_CALL(write_, _write(_)).WillOnce(Invoke([&](TLSMessage& msg) {
171  EXPECT_EQ(msg.type, ContentType::alert);
172  TLSContent content;
173  content.contentType = msg.type;
174  content.encryptionLevel = write_.getEncryptionLevel();
175  content.data = nullptr;
176  return content;
177  }));
178  write_.writeAlert(Alert());
179 }
180 
181 TEST_F(RecordTest, TestWriteHandshake) {
182  EXPECT_CALL(write_, _write(_)).WillOnce(Invoke([&](TLSMessage& msg) {
183  EXPECT_EQ(msg.type, ContentType::handshake);
184  TLSContent content;
185  content.contentType = msg.type;
186  content.encryptionLevel = write_.getEncryptionLevel();
187  content.data = nullptr;
188  return content;
189  }));
190  write_.writeHandshake(IOBuf::copyBuffer("msg1"), IOBuf::copyBuffer("msg2"));
191 }
192 } // namespace test
193 } // namespace fizz
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:1847
bool unhexlify(const InputString &input, OutputString &output)
Definition: String-inl.h:616
#define MOCK_CONST_METHOD1(m,...)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static void expectSame(const Buf &buf, const std::string &hex)
Definition: RecordTest.cpp:53
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
PolymorphicAction< internal::InvokeWithoutArgsAction< FunctionImpl > > InvokeWithoutArgs(FunctionImpl function_impl)
StrictMock< ConcreteWriteRecordLayer > write_
Definition: RecordTest.cpp:42
StrictMock< ConcreteReadRecordLayer > read_
Definition: RecordTest.cpp:41
static Options cacheChainLength()
Definition: IOBufQueue.h:83
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
size_t read(T &out, folly::io::Cursor &cursor)
Definition: Types-inl.h:258
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
static Buf getBuf(const std::string &hex)
Definition: RecordTest.cpp:48
EncryptionLevel encryptionLevel
Definition: RecordLayer.h:21
Definition: Actions.h:16
TEST_F(AsyncSSLSocketWriteTest, write_coalescing1)
TLSContent write(TLSMessage &&msg) const override
Definition: RecordTest.cpp:34
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define MOCK_METHOD1(m,...)
const char * string
Definition: Conv.cpp:212
ContentType contentType
Definition: RecordLayer.h:20
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
ContentType type
Definition: Types.h:55
bool hexlify(const InputString &input, OutputString &output, bool append_output)
Definition: String-inl.h:596
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
constexpr None none
Definition: Optional.h:87