2 * Copyright 2014 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "folly/wangle/bootstrap/ServerBootstrap.h"
18 #include "folly/wangle/bootstrap/ClientBootstrap.h"
19 #include "folly/wangle/channel/ChannelHandler.h"
21 #include <glog/logging.h>
22 #include <gtest/gtest.h>
24 using namespace folly::wangle;
25 using namespace folly;
27 typedef ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> Pipeline;
29 class TestServer : public ServerBootstrap<Pipeline> {
30 Pipeline* newPipeline(std::shared_ptr<AsyncSocket>) {
35 class TestClient : public ClientBootstrap<Pipeline> {
36 Pipeline* newPipeline(std::shared_ptr<AsyncSocket> sock) {
39 // We probably aren't connected immedately, check after a small delay
40 EventBaseManager::get()->getEventBase()->runAfterDelay([sock](){
41 CHECK(sock->readable());
47 class TestPipelineFactory : public PipelineFactory<Pipeline> {
49 Pipeline* newPipeline(std::shared_ptr<AsyncSocket> sock) {
51 return new Pipeline();
53 std::atomic<int> pipelines{0};
56 TEST(Bootstrap, Basic) {
61 TEST(Bootstrap, ServerWithPipeline) {
63 server.childPipeline(std::make_shared<TestPipelineFactory>());
68 TEST(Bootstrap, ClientServerTest) {
70 auto factory = std::make_shared<TestPipelineFactory>();
71 server.childPipeline(factory);
73 auto base = EventBaseManager::get()->getEventBase();
75 SocketAddress address;
76 server.getSockets()[0]->getAddress(&address);
79 client.connect(address);
83 CHECK(factory->pipelines == 1);
86 TEST(Bootstrap, ClientConnectionManagerTest) {
87 // Create a single IO thread, and verify that
88 // client connections are pooled properly
91 auto factory = std::make_shared<TestPipelineFactory>();
92 server.childPipeline(factory);
93 server.group(std::make_shared<IOThreadPoolExecutor>(1));
95 auto base = EventBaseManager::get()->getEventBase();
97 SocketAddress address;
98 server.getSockets()[0]->getAddress(&address);
101 client.connect(address);
104 client2.connect(address);
109 CHECK(factory->pipelines == 2);
112 TEST(Bootstrap, ServerAcceptGroupTest) {
113 // Verify that server is using the accept IO group
116 auto factory = std::make_shared<TestPipelineFactory>();
117 server.childPipeline(factory);
118 server.group(std::make_shared<IOThreadPoolExecutor>(1), nullptr);
121 SocketAddress address;
122 server.getSockets()[0]->getAddress(&address);
124 boost::barrier barrier(2);
125 auto thread = std::thread([&](){
127 client.connect(address);
128 EventBaseManager::get()->getEventBase()->loop();
135 CHECK(factory->pipelines == 1);
138 TEST(Bootstrap, ServerAcceptGroup2Test) {
139 // Verify that server is using the accept IO group
141 // Check if reuse port is supported, if not, don't run this test
144 auto serverSocket = AsyncServerSocket::newSocket(&base);
145 serverSocket->bind(0);
146 serverSocket->listen(0);
147 serverSocket->startAccepting();
148 serverSocket->setReusePortEnabled(true);
149 serverSocket->stopAccepting();
151 LOG(INFO) << "Reuse port probably not supported";
156 auto factory = std::make_shared<TestPipelineFactory>();
157 server.childPipeline(factory);
158 server.group(std::make_shared<IOThreadPoolExecutor>(4), nullptr);
161 SocketAddress address;
162 server.getSockets()[0]->getAddress(&address);
165 client.connect(address);
166 EventBaseManager::get()->getEventBase()->loop();
170 CHECK(factory->pipelines == 1);
173 TEST(Bootstrap, SharedThreadPool) {
174 auto pool = std::make_shared<IOThreadPoolExecutor>(2);
177 auto factory = std::make_shared<TestPipelineFactory>();
178 server.childPipeline(factory);
179 server.group(pool, pool);
183 SocketAddress address;
184 server.getSockets()[0]->getAddress(&address);
187 client.connect(address);
190 client2.connect(address);
193 client3.connect(address);
196 client4.connect(address);
199 client5.connect(address);
201 EventBaseManager::get()->getEventBase()->loop();
204 CHECK(factory->pipelines == 5);