4949import org .apache .thrift .transport .TFramedTransport ;
5050import org .apache .thrift .transport .TSocket ;
5151import org .apache .thrift .transport .TTransport ;
52- import org .apache .thrift .transport .TTransportException ;
5352import org .junit .AfterClass ;
5453import org .junit .BeforeClass ;
5554import org .junit .ClassRule ;
@@ -175,16 +174,40 @@ private int getRandomPort() {
175174 * Server can fail to bind if clashing address. Add retrying until we get a good server.
176175 */
177176 ThriftServer createBoundServer () {
178- return createBoundServer (false );
177+ return createBoundServer (false , false );
178+ }
179+
180+ private ServerSocket getBoundSocket () {
181+ ServerSocket ss = null ;
182+ while (true ) {
183+ port = getRandomPort ();
184+ try {
185+ ss = new ServerSocket ();
186+ ss .bind (new InetSocketAddress (port ));
187+ break ;
188+ } catch (IOException ioe ) {
189+ LOG .warn ("Failed bind" , ioe );
190+ try {
191+ ss .close ();
192+ } catch (IOException ioe2 ) {
193+ LOG .warn ("FAILED CLOSE of failed bind socket" , ioe2 );
194+ }
195+ }
196+ }
197+ return ss ;
179198 }
180199
181200 /**
182- * @param clash This param is just so we can manufacture a port clash so we can test the
183- * code does the right thing when this happens during actual test runs. Ugly but works.
184- * @see TestBindExceptionHandling#testPortClash ()
201+ * @param protocolPortClash This param is just so we can manufacture a port clash so we can test
202+ * the code does the right thing when this happens during actual test runs. Ugly but works.
203+ * @see TestBindExceptionHandling#testProtocolPortClash ()
185204 */
186- ThriftServer createBoundServer (boolean clash ) {
187- boolean testClashOfFirstPort = clash ;
205+ ThriftServer createBoundServer (boolean protocolPortClash , boolean infoPortClash ) {
206+ if (protocolPortClash && infoPortClash ) {
207+ throw new RuntimeException ("Can't set both at same time" );
208+ }
209+ boolean testClashOfFirstProtocolPort = protocolPortClash ;
210+ boolean testClashOfFirstInfoPort = infoPortClash ;
188211 List <String > args = new ArrayList <>();
189212 ServerSocket ss = null ;
190213 for (int i = 0 ; i < 100 ; i ++) {
@@ -194,22 +217,26 @@ ThriftServer createBoundServer(boolean clash) {
194217 assertTrue (serverTypeOption .startsWith ("-" ));
195218 args .add (serverTypeOption );
196219 }
197- port = getRandomPort ();
198- if (testClashOfFirstPort ) {
220+ if (testClashOfFirstProtocolPort ) {
199221 // Test what happens if already something bound to the socket.
200222 // Occupy the random port we just pulled.
201- try {
202- ss = new ServerSocket ();
203- ss .bind (new InetSocketAddress (port ));
204- } catch (IOException ioe ) {
205- LOG .warn ("Failed bind" , ioe );
206- }
207- testClashOfFirstPort = false ;
223+ ss = getBoundSocket ();
224+ port = ss .getLocalPort ();
225+ testClashOfFirstProtocolPort = false ;
226+ } else {
227+ port = getRandomPort ();
208228 }
209229 args .add ("-" + PORT_OPTION );
210230 args .add (String .valueOf (port ));
211231 args .add ("-" + INFOPORT_OPTION );
212- int infoPort = getRandomPort ();
232+ int infoPort ;
233+ if (testClashOfFirstInfoPort ) {
234+ ss = getBoundSocket ();
235+ infoPort = ss .getLocalPort ();
236+ testClashOfFirstInfoPort = false ;
237+ } else {
238+ infoPort = getRandomPort ();
239+ }
213240 args .add (String .valueOf (infoPort ));
214241
215242 if (specifyFramed ) {
@@ -230,9 +257,8 @@ ThriftServer createBoundServer(boolean clash) {
230257 for (int ii = 0 ; ii < 100 && (thriftServer .tserver == null ); ii ++) {
231258 Threads .sleep (100 );
232259 }
233- if (cmdLineException instanceof TTransportException &&
234- cmdLineException .getCause () instanceof BindException ) {
235- LOG .info ("Trying new port" , cmdLineException );
260+ if (isBindException (cmdLineException )) {
261+ LOG .info ("BindException; trying new port" , cmdLineException );
236262 cmdLineException = null ;
237263 thriftServer .stop ();
238264 continue ;
@@ -253,6 +279,20 @@ ThriftServer createBoundServer(boolean clash) {
253279 return thriftServer ;
254280 }
255281
282+ private boolean isBindException (Exception cmdLineException ) {
283+ if (cmdLineException == null ) {
284+ return false ;
285+ }
286+ if (cmdLineException instanceof BindException ) {
287+ return true ;
288+ }
289+ if (cmdLineException .getCause () != null &&
290+ cmdLineException .getCause () instanceof BindException ) {
291+ return true ;
292+ }
293+ return false ;
294+ }
295+
256296 @ Test
257297 public void testRunThriftServer () throws Exception {
258298 ThriftServer thriftServer = createBoundServer ();
0 commit comments