View Javadoc

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