You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by el...@apache.org on 2011/06/30 19:54:21 UTC

svn commit: r1141638 - in /hadoop/common/trunk/common: CHANGES.txt src/java/org/apache/hadoop/ipc/Client.java src/test/core/org/apache/hadoop/ipc/TestIPC.java

Author: eli
Date: Thu Jun 30 17:54:20 2011
New Revision: 1141638

URL: http://svn.apache.org/viewvc?rev=1141638&view=rev
Log:
HADOOP-7428. IPC connection is orphaned with null 'out' member. Contributed by Todd Lipcon

Modified:
    hadoop/common/trunk/common/CHANGES.txt
    hadoop/common/trunk/common/src/java/org/apache/hadoop/ipc/Client.java
    hadoop/common/trunk/common/src/test/core/org/apache/hadoop/ipc/TestIPC.java

Modified: hadoop/common/trunk/common/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/common/CHANGES.txt?rev=1141638&r1=1141637&r2=1141638&view=diff
==============================================================================
--- hadoop/common/trunk/common/CHANGES.txt (original)
+++ hadoop/common/trunk/common/CHANGES.txt Thu Jun 30 17:54:20 2011
@@ -337,6 +337,9 @@ Trunk (unreleased changes)
 
     HADOOP-7402. TestConfiguration doesn't clean up after itself. (atm via eli)
 
+    HADOOP-7428. IPC connection is orphaned with null 'out' member.
+    (todd via eli)
+
 Release 0.22.0 - Unreleased
 
   INCOMPATIBLE CHANGES

Modified: hadoop/common/trunk/common/src/java/org/apache/hadoop/ipc/Client.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/common/src/java/org/apache/hadoop/ipc/Client.java?rev=1141638&r1=1141637&r2=1141638&view=diff
==============================================================================
--- hadoop/common/trunk/common/src/java/org/apache/hadoop/ipc/Client.java (original)
+++ hadoop/common/trunk/common/src/java/org/apache/hadoop/ipc/Client.java Thu Jun 30 17:54:20 2011
@@ -583,8 +583,12 @@ public class Client {
           start();
           return;
         }
-      } catch (IOException e) {
-        markClosed(e);
+      } catch (Throwable t) {
+        if (t instanceof IOException) {
+          markClosed((IOException)t);
+        } else {
+          markClosed(new IOException("Couldn't set up IO streams", t));
+        }
         close();
       }
     }

Modified: hadoop/common/trunk/common/src/test/core/org/apache/hadoop/ipc/TestIPC.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/common/src/test/core/org/apache/hadoop/ipc/TestIPC.java?rev=1141638&r1=1141637&r2=1141638&view=diff
==============================================================================
--- hadoop/common/trunk/common/src/test/core/org/apache/hadoop/ipc/TestIPC.java (original)
+++ hadoop/common/trunk/common/src/test/core/org/apache/hadoop/ipc/TestIPC.java Thu Jun 30 17:54:20 2011
@@ -23,6 +23,7 @@ import org.apache.commons.logging.*;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.io.Writable;
 import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.net.NetUtils;
 
@@ -45,6 +46,9 @@ import static org.mockito.Mockito.*;
 
 import org.apache.hadoop.conf.Configuration;
 import org.junit.Assume;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import com.google.common.primitives.Bytes;
 import com.google.common.primitives.Ints;
@@ -469,6 +473,53 @@ public class TestIPC {
     }
   }
 
+  /**
+   * Test that, if a RuntimeException is thrown after creating a socket
+   * but before successfully connecting to the IPC server, that the
+   * failure is handled properly. This is a regression test for
+   * HADOOP-7428.
+   */
+  @Test
+  public void testRTEDuringConnectionSetup() throws Exception {
+    // Set up a socket factory which returns sockets which
+    // throw an RTE when setSoTimeout is called.
+    SocketFactory spyFactory = spy(NetUtils.getDefaultSocketFactory(conf));
+    Mockito.doAnswer(new Answer<Socket>() {
+      @Override
+      public Socket answer(InvocationOnMock invocation) throws Throwable {
+        Socket s = spy((Socket)invocation.callRealMethod());
+        doThrow(new RuntimeException("Injected fault")).when(s)
+          .setSoTimeout(anyInt());
+        return s;
+      }
+    }).when(spyFactory).createSocket();
+      
+    Server server = new TestServer(1, true);
+    server.start();
+    try {
+      // Call should fail due to injected exception.
+      InetSocketAddress address = NetUtils.getConnectAddress(server);
+      Client client = new Client(LongWritable.class, conf, spyFactory);
+      try {
+        client.call(new LongWritable(RANDOM.nextLong()),
+                address, null, null, 0, conf);
+        fail("Expected an exception to have been thrown");
+      } catch (Exception e) {
+        LOG.info("caught expected exception", e);
+        assertTrue(StringUtils.stringifyException(e).contains(
+            "Injected fault"));
+      }
+      // Resetting to the normal socket behavior should succeed
+      // (i.e. it should not have cached a half-constructed connection)
+  
+      Mockito.reset(spyFactory);
+      client.call(new LongWritable(RANDOM.nextLong()),
+          address, null, null, 0, conf);
+    } finally {
+      server.stop();
+    }
+  }
+  
   @Test
   public void testIpcTimeout() throws Exception {
     // start server