proxygen
ThreadSafeSSLSessionCacheTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
18 #include <folly/Conv.h>
19 #include <folly/Memory.h>
20 
21 #include <thread>
22 #include <gtest/gtest.h>
23 #include <gmock/gmock.h>
24 
25 using namespace testing;
26 using namespace wangle;
27 
28 // One time use cache for testing.
30  public:
32  const std::string& identity,
33  SSLSessionPtr session) noexcept override {
34  cache_.emplace(identity, std::move(session));
35  }
36 
37  SSLSessionPtr getSSLSession(const std::string& identity) const
38  noexcept override {
39  auto it = cache_.find(identity);
40  if (it == cache_.end()) {
41  return SSLSessionPtr(nullptr);
42  }
43  auto sess = std::move(it->second);
44  cache_.erase(it);
45  return sess;
46  }
47 
48  bool removeSSLSession(const std::string& /* identity */) noexcept override {
49  return true;
50  }
51 
52  private:
53  mutable std::map<std::string, SSLSessionPtr> cache_;
54 };
55 
57  public:
59 
60  void SetUp() override {
61  for (auto& it : getSessions()) {
62  sessions_.emplace_back(it.first, it.second);
63  }
64  cache_.reset(new ThreadSafeSSLSessionCache(
65  std::make_unique<FakeSessionCallbacks>()));
66  }
67 
68  std::vector<std::pair<SSL_SESSION*, size_t>> sessions_;
69  std::unique_ptr<ThreadSafeSSLSessionCache> cache_;
70 };
71 
73  const size_t numRounds = 100;
74 
75  size_t writeOps = 0;
76  size_t readOps = 0;
77 
78  std::thread writer([&] () {
79  for (size_t j = 0; j < numRounds; ++j) {
80  for (size_t i = 0; i < sessions_.size(); ++i) {
81  writeOps++;
82  cache_->setSSLSession(
83  folly::to<std::string>("host ", j, i),
84  createPersistentTestSession(sessions_[i]));
85  }
86  }
87  });
88 
89  std::thread reader([&] () {
90  for (size_t j = 0; j < numRounds; ++j) {
91  for (size_t i = 0; i < sessions_.size(); ++i) {
92  readOps++;
93  auto sess = cache_->getSSLSession(
94  folly::to<std::string>("host ", j, i));
95  if (!sess) {
96  // spinlock around the session.
97  i--;
98  }
99  }
100  }
101  });
102 
103  writer.join();
104  reader.join();
105  EXPECT_GE(readOps, writeOps);
106 }
SSLSessionPtr createPersistentTestSession(std::pair< SSL_SESSION *, size_t > session)
Definition: TestUtil.cpp:350
TEST_F(TestInfoTest, Names)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< ThreadSafeSSLSessionCache > cache_
void setSSLSession(const std::string &identity, SSLSessionPtr session) noexceptoverride
requires E e noexcept(noexcept(s.error(std::move(e))))
#define EXPECT_GE(val1, val2)
Definition: gtest.h:1932
std::unique_ptr< SSL_SESSION, SessionDestructor > SSLSessionPtr
Definition: SSLSession.h:32
std::vector< std::pair< SSL_SESSION *, size_t > > getSessions()
Definition: TestUtil.cpp:320
SSLSessionPtr getSSLSession(const std::string &identity) const noexceptoverride
const char * string
Definition: Conv.cpp:212
std::vector< std::pair< SSL_SESSION *, size_t > > sessions_
bool removeSSLSession(const std::string &) noexceptoverride