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