1 /*
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 #ifdef _WIN32
21 
22 #include <boost/test/test_tools.hpp>
23 #include <boost/test/unit_test_suite.hpp>
24 
25 #include <boost/chrono/duration.hpp>
26 #include <boost/date_time/posix_time/posix_time_duration.hpp>
27 #include <boost/thread/thread.hpp>
28 #include <thrift/transport/TPipe.h>
29 #include <thrift/transport/TPipeServer.h>
30 #include <thrift/stdcxx.h>
31 
32 using apache::thrift::transport::TPipeServer;
33 using apache::thrift::transport::TPipe;
34 using apache::thrift::transport::TTransport;
35 using apache::thrift::transport::TTransportException;
36 using namespace apache::thrift;
37 
38 BOOST_AUTO_TEST_SUITE(TPipeInterruptTest)
39 
40 // TODO: duplicate the test cases in TSocketInterruptTest for pipes,
41 // once pipes implement interruptChildren
42 
BOOST_AUTO_TEST_CASE(test_interrupt_before_accept)43 BOOST_AUTO_TEST_CASE(test_interrupt_before_accept) {
44   TPipeServer pipe1("TPipeInterruptTest");
45   pipe1.listen();
46   pipe1.interrupt();
47   BOOST_CHECK_THROW(pipe1.accept(), TTransportException);
48 }
49 
acceptWorker(TPipeServer * pipe)50 static void acceptWorker(TPipeServer *pipe) {
51   try
52   {
53     for (;;)
54     {
55       stdcxx::shared_ptr<TTransport> temp = pipe->accept();
56     }
57   }
58   catch (...) {/*just want to make sure nothing crashes*/ }
59 }
60 
interruptWorker(TPipeServer * pipe)61 static void interruptWorker(TPipeServer *pipe) {
62   boost::this_thread::sleep(boost::posix_time::milliseconds(10));
63   pipe->interrupt();
64 }
65 
BOOST_AUTO_TEST_CASE(stress_pipe_accept_interruption)66 BOOST_AUTO_TEST_CASE(stress_pipe_accept_interruption) {
67   int interruptIters = 10;
68 
69   for (int i = 0; i < interruptIters; ++i)
70   {
71     TPipeServer pipeServer("TPipeInterruptTest");
72     pipeServer.listen();
73     boost::thread acceptThread(stdcxx::bind(acceptWorker, &pipeServer));
74     boost::thread interruptThread(stdcxx::bind(interruptWorker, &pipeServer));
75     try
76     {
77       for (;;)
78       {
79         TPipe client("TPipeInterruptTest");
80         client.setConnTimeout(1);
81         client.open();
82       }
83     } catch (...) { /*just testing for crashes*/ }
84     interruptThread.join();
85     acceptThread.join();
86   }
87 }
88 
89 BOOST_AUTO_TEST_SUITE_END()
90 #endif
91