View Javadoc

1   /*
2    * $Id: SocketTimingExperimentTestCase.java 20321 2010-11-24 15:21:24Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.tcp.other;
12  
13  import org.mule.tck.AbstractMuleTestCase;
14  
15  import java.io.IOException;
16  import java.net.InetSocketAddress;
17  import java.net.ServerSocket;
18  import java.net.Socket;
19  
20  /**
21   * This was an attempt to understand the issue we saw with HTTP closing early.
22   * Unfortunately, it doesn't shed any light on the problem.
23   */
24  public class SocketTimingExperimentTestCase extends AbstractMuleTestCase
25  {
26  
27      private static int MAX_COUNT = 3;
28      private static int SERVER_PORT = 60323;
29      private static String LOCALHOST = "localhost";
30  
31      public void testSocketTiming() throws IOException, InterruptedException
32      {
33          try
34          {
35              boolean expectBadClient = expectBadClient();
36              logger.info("Expected bad client: " + expectBadClient);
37          }
38          catch (Exception e)
39          {
40              logger.info(e);
41          }
42          try
43          {
44              boolean expectBadServer = expectBadServer();
45              logger.info("Expected bad server: " + expectBadServer);
46          }
47          catch (Exception e)
48          {
49              logger.info(e);
50          }
51      }
52  
53      protected boolean expectBadClient() throws IOException, InterruptedException
54      {
55          for (int i = 0; i < MAX_COUNT; ++i)
56          {
57              if (! expectBadClientSingle())
58              {
59                  return false;
60              }
61          }
62          return true;
63      }
64  
65      protected boolean expectBadClientSingle() throws IOException, InterruptedException
66      {
67          ServerSocket server = new ServerSocket();
68          try {
69              server.bind(new InetSocketAddress(LOCALHOST, SERVER_PORT));
70              return badSend(new Socket(LOCALHOST, SERVER_PORT), server.accept(), null);
71          }
72          finally
73          {
74              server.close();
75          }
76      }
77  
78      protected boolean badSend(Socket from, Socket to, ServerSocket server) throws IOException, InterruptedException
79      {
80          try
81          {
82              // reduce buffers so that they are easy to fill
83              to.setReceiveBufferSize(1);
84              from.setSendBufferSize(1);
85              // just in case this reduces close time
86  //            from.setReuseAddress(true);
87              // make linger very small (same result if false or zero, or omitted)
88              from.setSoLinger(false, 0);
89              to.setSoLinger(false, 0);
90              // don't send until buffer full (should be default)
91              to.setTcpNoDelay(false);
92              from.setTcpNoDelay(false);
93              // write two bytes to the buffer - this is more than the target can receive
94              // so we should end up with one byte in receiver and one in sender
95              from.getOutputStream().write(1);
96              from.getOutputStream().write(2);
97              // this blocks, confirming buffers are correct
98              // OH NO IT DOESN'T
99              from.getOutputStream().write(3);
100             // this appears to block (no timeout)
101 //            from.getOutputStream().write(new byte[100000]);
102             // close (before buffer sent)
103             // close everything we can think of...
104 //            from.shutdownInput();
105 //            from.shutdownOutput();
106             from.close();
107 //            to.shutdownOutput();
108             if (null != server)
109             {
110                 server.close();
111             }
112             // make sure tcp has time to fail
113             Thread.sleep(100);
114             // this works when server is closed (bad server case)
115             if (null != server)
116             {
117                 ServerSocket another = new ServerSocket();
118                 another.bind(new InetSocketAddress(LOCALHOST, SERVER_PORT));
119                 another.setReuseAddress(true);
120                 Socket another2 = new Socket(LOCALHOST, SERVER_PORT);
121                 Socket another3 = another.accept();
122                 another2.getOutputStream().write(9);
123                 assertEquals(9, another3.getInputStream().read());
124                 another3.close();
125                 another2.close();
126                 another.close();
127             }
128             // now try reading - this should fail on second value?
129             return 1 == to.getInputStream().read()
130                     && 2 == to.getInputStream().read()
131                     && 3 == to.getInputStream().read();
132         }
133         finally
134         {
135             to.close();
136             if (!from.isClosed())
137             {
138                  from.close();
139             }
140         }
141     }
142 
143     protected boolean expectBadServer() throws IOException, InterruptedException
144     {
145         for (int i = 0; i < MAX_COUNT; ++i)
146         {
147             if (! expectBadServerSingle())
148             {
149                 return false;
150             }
151         }
152         return true;
153     }
154 
155     protected boolean expectBadServerSingle() throws IOException, InterruptedException
156     {
157         ServerSocket server = new ServerSocket();
158         try {
159             server.bind(new InetSocketAddress(LOCALHOST, SERVER_PORT));
160             Socket client = new Socket(LOCALHOST, SERVER_PORT);
161             return badSend(server.accept(), client, server);
162         }
163         finally
164         {
165             server.close();
166         }
167     }
168 
169 }