blob: b6c41667b8f78d5891f44e0f4174a9764a6a9e30 [file] [log] [blame]
Nobuaki Sukegawad0d7a652014-12-07 21:36:51 +09001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#define BOOST_TEST_MODULE TNonblockingServerTest
21#include <boost/test/unit_test.hpp>
22#include <boost/smart_ptr.hpp>
23
24#include "thrift/concurrency/Thread.h"
25#include "thrift/server/TNonblockingServer.h"
26
27#include "gen-cpp/ParentService.h"
28
29using namespace apache::thrift;
30
31struct Handler : public test::ParentServiceIf {
32 void addString(const std::string& s) { strings_.push_back(s); }
33 void getStrings(std::vector<std::string>& _return) { _return = strings_; }
34 std::vector<std::string> strings_;
35
36 // dummy overrides not used in this test
37 int32_t incrementGeneration() { return 0; }
38 int32_t getGeneration() { return 0; }
39 void getDataWait(std::string&, int32_t) {}
40 void onewayWait() {}
41 void exceptionWait(const std::string&) {}
42 void unexpectedExceptionWait(const std::string&) {}
43};
44
45class Fixture {
46private:
47 struct Runner : public concurrency::Runnable {
48 boost::shared_ptr<server::TNonblockingServer> server;
49 bool error;
50 virtual void run() {
51 error = false;
52 try {
53 server->serve();
54 } catch (const TException& x) {
55 error = true;
56 }
57 }
58 };
59
60protected:
61 Fixture() : processor(new test::ParentServiceProcessor(boost::make_shared<Handler>())) {}
62
63 int startServer(int port) {
64 boost::scoped_ptr<concurrency::ThreadFactory> threadFactory(
65 new concurrency::PlatformThreadFactory(
66#if !defined(USE_BOOST_THREAD) && !defined(USE_STD_THREAD)
67 concurrency::PlatformThreadFactory::OTHER,
68 concurrency::PlatformThreadFactory::NORMAL,
69 1,
70#endif
71 true));
72
73 int retry_count = port ? 10 : 0;
74 for (int p = port; p <= port + retry_count; p++) {
75 server.reset(new server::TNonblockingServer(processor, p));
76 boost::shared_ptr<Runner> runner(new Runner);
77 runner->server = server;
78 thread = threadFactory->newThread(runner);
79 thread->start();
80 // wait 50ms for the server to begin listening
81 THRIFT_SLEEP_USEC(50000);
82 if (!runner->error) {
83 return p;
84 }
85 }
86 throw transport::TTransportException(transport::TTransportException::NOT_OPEN,
87 "Failed to start server.");
88 }
89
90 bool canCommunicate(int serverPort) {
91 boost::shared_ptr<transport::TSocket> socket(new transport::TSocket("localhost", serverPort));
92 socket->open();
93 test::ParentServiceClient client(boost::make_shared<protocol::TBinaryProtocol>(
94 boost::make_shared<transport::TFramedTransport>(socket)));
95 client.addString("foo");
96 std::vector<std::string> strings;
97 client.getStrings(strings);
98 return strings.size() == 1 && !(strings[0].compare("foo"));
99 }
100
101private:
102 boost::shared_ptr<test::ParentServiceProcessor> processor;
103 boost::shared_ptr<concurrency::Thread> thread;
104
105protected:
106 boost::shared_ptr<server::TNonblockingServer> server;
107};
108
109BOOST_AUTO_TEST_SUITE(TNonblockingServerTest)
110
111BOOST_FIXTURE_TEST_CASE(get_specified_port, Fixture) {
112 int specified_port = startServer(12345);
113 BOOST_REQUIRE_GE(specified_port, 12345);
114 BOOST_REQUIRE_EQUAL(server->getListenPort(), specified_port);
115 BOOST_CHECK(canCommunicate(specified_port));
116
117 server->stop();
118 BOOST_CHECK_EQUAL(server->getListenPort(), specified_port);
119}
120
121BOOST_FIXTURE_TEST_CASE(get_assigned_port, Fixture) {
122 int specified_port = startServer(0);
123 BOOST_REQUIRE_EQUAL(specified_port, 0);
124 int assigned_port = server->getListenPort();
125 BOOST_REQUIRE_NE(assigned_port, 0);
126 BOOST_CHECK(canCommunicate(assigned_port));
127
128 server->stop();
129 BOOST_CHECK_EQUAL(server->getListenPort(), 0);
130}
131
132BOOST_AUTO_TEST_SUITE_END()