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 typedef ServerBootstrap<Pipeline> TestServer;
30 typedef ClientBootstrap<Pipeline> TestClient;
32 class TestClientPipelineFactory : public PipelineFactory<Pipeline> {
34 Pipeline* newPipeline(std::shared_ptr<AsyncSocket> sock) {
37 // We probably aren't connected immedately, check after a small delay
38 EventBaseManager::get()->getEventBase()->runAfterDelay([sock](){
39 CHECK(sock->readable());
45 class TestPipelineFactory : public PipelineFactory<Pipeline> {
47 Pipeline* newPipeline(std::shared_ptr<AsyncSocket> sock) {
49 return new Pipeline();
51 std::atomic<int> pipelines{0};
54 TEST(Bootstrap, Basic) {
59 TEST(Bootstrap, ServerWithPipeline) {
61 server.childPipeline(std::make_shared<TestPipelineFactory>());
66 TEST(Bootstrap, ClientServerTest) {
68 auto factory = std::make_shared<TestPipelineFactory>();
69 server.childPipeline(factory);
71 auto base = EventBaseManager::get()->getEventBase();
73 SocketAddress address;
74 server.getSockets()[0]->getAddress(&address);
77 client.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
78 client.connect(address);
82 CHECK(factory->pipelines == 1);
85 TEST(Bootstrap, ClientConnectionManagerTest) {
86 // Create a single IO thread, and verify that
87 // client connections are pooled properly
90 auto factory = std::make_shared<TestPipelineFactory>();
91 server.childPipeline(factory);
92 server.group(std::make_shared<IOThreadPoolExecutor>(1));
94 auto base = EventBaseManager::get()->getEventBase();
96 SocketAddress address;
97 server.getSockets()[0]->getAddress(&address);
100 client.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
102 client.connect(address);
105 client2.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
106 client2.connect(address);
111 CHECK(factory->pipelines == 2);
114 TEST(Bootstrap, ServerAcceptGroupTest) {
115 // Verify that server is using the accept IO group
118 auto factory = std::make_shared<TestPipelineFactory>();
119 server.childPipeline(factory);
120 server.group(std::make_shared<IOThreadPoolExecutor>(1), nullptr);
123 SocketAddress address;
124 server.getSockets()[0]->getAddress(&address);
126 boost::barrier barrier(2);
127 auto thread = std::thread([&](){
129 client.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
130 client.connect(address);
131 EventBaseManager::get()->getEventBase()->loop();
138 CHECK(factory->pipelines == 1);
141 TEST(Bootstrap, ServerAcceptGroup2Test) {
142 // Verify that server is using the accept IO group
144 // Check if reuse port is supported, if not, don't run this test
147 auto serverSocket = AsyncServerSocket::newSocket(&base);
148 serverSocket->bind(0);
149 serverSocket->listen(0);
150 serverSocket->startAccepting();
151 serverSocket->setReusePortEnabled(true);
152 serverSocket->stopAccepting();
154 LOG(INFO) << "Reuse port probably not supported";
159 auto factory = std::make_shared<TestPipelineFactory>();
160 server.childPipeline(factory);
161 server.group(std::make_shared<IOThreadPoolExecutor>(4), nullptr);
164 SocketAddress address;
165 server.getSockets()[0]->getAddress(&address);
168 client.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
170 client.connect(address);
171 EventBaseManager::get()->getEventBase()->loop();
175 CHECK(factory->pipelines == 1);
178 TEST(Bootstrap, SharedThreadPool) {
179 // Check if reuse port is supported, if not, don't run this test
182 auto serverSocket = AsyncServerSocket::newSocket(&base);
183 serverSocket->bind(0);
184 serverSocket->listen(0);
185 serverSocket->startAccepting();
186 serverSocket->setReusePortEnabled(true);
187 serverSocket->stopAccepting();
189 LOG(INFO) << "Reuse port probably not supported";
193 auto pool = std::make_shared<IOThreadPoolExecutor>(2);
196 auto factory = std::make_shared<TestPipelineFactory>();
197 server.childPipeline(factory);
198 server.group(pool, pool);
202 SocketAddress address;
203 server.getSockets()[0]->getAddress(&address);
206 client.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
207 client.connect(address);
210 client2.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
211 client2.connect(address);
214 client3.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
215 client3.connect(address);
218 client4.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
219 client4.connect(address);
222 client5.pipelineFactory(std::make_shared<TestClientPipelineFactory>());
223 client5.connect(address);
225 EventBaseManager::get()->getEventBase()->loop();
228 CHECK(factory->pipelines == 5);